我在文件中有这些类型的记录:
1867 121 2 56
1868 121 1 6
1868 121 2 65
1868 122 0 53
1869 121 0 41
1869 121 1 41
1871 121 1 13
1871 121 2 194
我想得到这个输出:
1867 121 2 56
1868 121 1 6
1868 121 2 65
1868 122 0 53
1869 121 0 41
1869 121 1 41
1870 121 0 0
1871 121 1 13
1871 121 2 194
区别在于 1870 121 0 0
行。
因此,如果第一列中的数字之间的差异大于 1,那么我们必须包含一个包含缺失数字的行(上面的例子是 1870
)和其他列.应该以某种方式获取其他列,让第二列成为列数可能值的最小值(在示例中,这些值可能是 121
或 122
),并且与第三列的情况相同。最后一列的值始终为零。
有人可以给我一些建议吗?提前致谢!
我正在尝试用 awk
解决它,但也许有其他更好或更实用的解决方案...
最佳答案
像这样的东西可以工作-
awk 'BEGIN{getline;a=$1;b=$2;c=$3}
NR==FNR{if (b>$2) b=$2; if (c>$3) c=$3;next}
{if ($1-a>1) {x=($1-a); for (i=1;i<x;i++) {print (a+1)"\t"b,c,"0";a++};a=$1} else a=$1;print}' file file
说明:
BEGIN{getline;a=$1;b=$2;c=$3}
-在这个
BEGIN
block 我们读取第一行并在column 1
中赋值到变量a
,column 2
到变量b
和column 3
到变量c
.NR==FNR{if (b>$2) b=$2; if (c>$3) c=$3;next}
-在此我们扫描整个文件 (
NR==FNR
) 并跟踪column 2
中可能的最低值和column 3
并将它们存储在变量中b
和c
分别。我们使用next
避免运行第二个pattern{action}
陈述。{if ($1-a>1) {x=($1-a); for (i=1;i<x;i++) {print (a+1)"\t"b,c,"0";a++};a=$1} else a=$1;print}
-这
action
语句检查column 1
中的值并将其与a
进行比较.如果差异大于 1,我们执行for loop
添加所有缺失的行并设置a
的值至$1
.如果column 1
中的值在连续的行上不大于 1,我们分配值column 1
至a
和print
它。
测试:
[jaypal:~/Temp] cat file
1867 121 2 56
1868 121 1 6
1868 121 2 65
1868 122 0 53
1869 121 0 41
1869 121 1 41
1871 121 1 13 # <--- 1870 skipped
1871 121 2 194
1875 120 1 12 # <--- 1872, 1873, 1874 skipped
[jaypal:~/Temp] awk 'BEGIN{getline;a=$1;b=$2;c=$3}
NR==FNR{if (b>$2) b=$2; if (c>$3) c=$3;next}
{if ($1-a>1) {x=($1-a); for (i=1;i<x;i++) {print (a+1)"\t"b,c,"0";a++};a=$1} else a=$1;print}' file file
1867 121 2 56
1868 121 1 6
1868 121 2 65
1868 122 0 53
1869 121 0 41
1869 121 1 41
1870 120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1871 121 1 13
1871 121 2 194
1872 120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1873 120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1874 120 0 0 # Assigned minimum value in col 2 (120) and col 3 (0).
1875 120 1 12
关于linux - 补充模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8736039/