linux - 仅用 awk 替换 sed/tail/grep
问题描述
我有以下任务要完成。我一起使用 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 到第二行的所有内容
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
在第二个文件中,如果我们不在较新的行中并且行 equals 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,但我会说在实践中足够接近和更好。
推荐阅读
- laravel - 如何将文件上传保存在本地文件夹 Laravel
- php - 使用 Docker 时,SOAP 无法解析 SSL 请求
- verilog - Verilog 中的 4 位 SR 锁存器
- java - 使用杰克逊从字符串反序列化 LocalDateTime
- express - 在 Actions on Google 中使用 Express 中间件
- r - 使用 Rstudio 运行多个 exe 文件
- ignite - 在多个节点上配置 Apache Ignite 集群
- javascript - 水平多个 Div - 滑动打开/关闭 Div
- python - 无法使用反卷积层训练 VAE
- mysql - 如何在 AWS 中查找 MySQL 数据库