我的输入文件的字段用冒号分隔:
主要的:
one:111:222:333
fiv:333:222:333
two:123:234:500
文件1:
one:111:222:333
two:123:234:501
文件2:
one:111:222:333
thr:-:234:232
fiv:999:500:232
感谢提示关联我对 awk 代码做了一些修改:
$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500
为什么它也打印行thr:-:234:232
?由于thr
主文件中没有发生,因此应忽略其中的任何更新。更新应该仅是基于第一列的这些行,该行存在于主文件中,并且与第一列对应的行存在于 file1 或 file2 中,并且在第三列中具有更大的值。
为什么$2~/[0-9]+/
在这里不起作用?
更新:还是没弄清楚,请看一下:
当我将测试主文件修改为:
one:111:222:333 fiv:333:222:333 two:123:234:500 ten.233:422:452
并运行以下 awk 命令:
$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else print; }' file* main
thr:-:234:232
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500
ten.233:422:452
因此输出是错误的,因为 thr 行不应该出现在输出上,因为它thr
不在main
文件中
我修改了命令,添加了附加条件else if($1 in a) {print};
,但它不会在主文件中打印以“ten”开头的行:
$ awk -F':' -vf=main 'FILENAME==f{m=$0};FILENAME!=f&&$2~/[0-9]+/{if ($2~/[0-9]+/&&(!($1 in a) || $3 > a[$1])) { a[$1] = $3; b[$1] = $0 } next;}{if (($1 in a) && (a[$1] > $3)){ print b[$1]":updated:"m; delete b[$1] } else if($1 in a) {print}; }' file* main
one:111:222:333
fiv:999:500:232:updated:fiv:333:222:333
two:123:234:500
我将非常感谢任何帮助。
awk 真的非常棒,不幸的是我不是程序员,还无法自己弄清楚它。
答案1
因为你next
在块中有条件FILENAME != f && $2 ~ /[0-9]+/
。该thr
行不满足该条件,因此它落入“每行”块。在那里,$1 不存在a
,因此输入该else
块并打印该行。
我相信,如果您使用合理的缩进,您就能自己弄清楚这一点,这样您就可以真正看到您的程序:
awk -F':' -vf=main '
FILENAME == f {m = $0}
FILENAME != f && $2 ~ /[0-9]+/ {
if ($2 ~ /[0-9]+/ && (!($1 in a) || $3 > a[$1])) {
a[$1] = $3
b[$1] = $0
}
next
}
{
if (($1 in a) && (a[$1] > $3)) {
print b[$1]":updated:"m
delete b[$1]
} else
print
}
' file* main