仅用awk替换sed/tail/grep



我有以下任务要完成。我一起使用awk/sed/tail/grep一起完成了它,但我相信仅使用awk是可行的-因此我请求您的帮助:

什么是 awk 语法 -

  1. 从文件 A 获取最后一行(csv 格式(

LAST=$(tail -n1 A)

  1. 检查文件 A 中的行是否存在于文件 B(csv 也是如此(,如果是......

NO=$(grep -nw "$LAST" B|awk -F: {print $1})'

  1. 检查文件 B 中是否有更新的行,如果是...
BELOW=$(expr $NO + 1)
if awk "NR==$BELOW" B; then
  1. 删除文件 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 中,但我会说足够接近,在实践中更好。

最新更新