我有以下任务要完成。我一起使用awk/sed/tail/grep一起完成了它,但我相信仅使用awk是可行的-因此我请求您的帮助:
什么是 awk 语法 -
- 从文件 A 获取最后一行(csv 格式(
LAST=$(tail -n1 A)
- 检查文件 A 中的行是否存在于文件 B(csv 也是如此(,如果是......
NO=$(grep -nw "$LAST" B|awk -F: {print $1})'
- 检查文件 B 中是否有更新的行,如果是...
BELOW=$(expr $NO + 1)
if awk "NR==$BELOW" B; then
- 删除文件 B 中从 $NO 到第 2 行的所有内容
sed -i "2,$NO d" B; fi
非常感谢任何帮助 - 赞赏!
这样的事情可能会起作用:
awk 'FNR == NR { last = $0; next }
!newer && $0 == last { newer = 1; next }
newer || FNR == 1' A B
基本上FNR == NR { last = $0; next }
只要我们在第一个文件中,last
设置到每一行,所以最终它将是第一个文件的最后一行。
在第二个文件中,如果我们不在较新的行中并且该行等于last
,下一行比第一个文件中的更新:!newer && $0 == last { newer = 1; next }
.
当我们在第二个文件的第一行或较新的行时,它会打印出来:newer || FNR == 1
.
这与原始版本的不同之处在于,它打印出 B 的新行,而不是就地修改 B。当然,您可以将输出重定向到 shell 中的临时文件,如果它包含多行,则将其移动到 B 上。或者让 Awk 返回退出状态并使用它,例如:
tmpf=`mktemp B'.XXXXXX'`
awk 'FNR == NR { last = $0; next }
!newer && $0 == last { newer = NR; next }
newer || FNR == 1 { print }
END { exit (!newer || NR == newer) }'
A B >"$tmpf" && mv "$tmpf" B || rm -f "$tmpf"
诚然,不再完全在 Awk 中,但我会说足够接近,在实践中更好。