繁体   English   中英

awk模式始终匹配最后一条记录吗?

[英]Awk pattern always matches last record?

我正在从zsh切换到bash的过程中,我需要生成一个bash脚本,该脚本可以删除$PATH中的重复条目而无需重新排序条目(因此没有sort -d魔术)。 zsh有一些不错的数组处理快捷方式,可以轻松高效地完成此操作,但是我不了解bash中的此类快捷方式。 我遇到了这个答案该答案已经使我90%地解决了问题,但是我想更好地理解这个小问题。 看来,当我运行该awk命令时,最后处理的记录不正确地匹配了模式。

$ awk 'BEGIN{RS=ORS=":"}!a[$0]++' <<<"aa:bb:cc:aa:bb:cc"
aa:bb:cc:cc
$ awk 'BEGIN{RS=ORS=":"}!a[$0]++' <<<"aa:bb:cc:aa:bb"
aa:bb:cc:bb
$ awk 'BEGIN{RS=ORS=":"}!a[$0]++' <<<"aa:bb:cc:aa:bb:cc:" # note trailing colon
aa:bb:cc:

我对awk不太了解,无法知道为什么会这样,但是我设法通过使用中间数组来解决此问题。

array=($(awk 'BEGIN{RS=":";ORS=" "}!a[$0]++' <<<"aa:bb:cc:aa:bb:cc:"))
# Use a subshell to avoid modifying $IFS in current context
echo $(export IFS=":"; echo "${array[*]}")
aa:bb:cc

但是,这似乎是次优的解决方案,所以我的问题是:我在awk命令中是否做错了什么,导致在处理的最终记录上出现假肯定匹配?

原始字符串中的最后一条记录是cc\\n ,与cc不同。 如果不确定以任何语言在任何程序中发生了什么,添加一些打印语句就是调试/调查的第一步。

$ awk 'BEGIN{RS=ORS=":"} {print "<"$0">"}' <<<"aa:bb:cc:aa:bb:cc"
<aa>:<bb>:<cc>:<aa>:<bb>:<cc
>:$

如果您希望RS为:\\n只需声明一下(至少使用GNU awk):

$ awk 'BEGIN{RS="[:\n]"; ORS=":"} !a[$0]++' <<<"aa:bb:cc:aa:bb:cc"
aa:bb:cc:$

以上所有的$都是我的提示。

另一种可能的解决方法,而不是您的bash阵列解决方案

$ echo "aa:bb:cc:aa:bb:cc" | tr ':' '\n' | awk '!a[$0]++' | paste -sd:
aa:bb:cc

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM