如何使用shell脚本将不包含特定模式的文件行追加到末尾

4

我有一个如下的平面文件:

11|aaa
11|bbb|NO|xxx
11|ccc
11|ddd|NO|yyy

对于不包含|NO|的行,我希望在末尾添加字符串|YES|。因此,我的文件应该如下所示:

11|aaa|YES|
11|bbb|NO|xxx
11|ccc|YES|
11|ddd|NO|yyy

我正在使用AIX系统并且无法使用sed -i命令进行内联替换。因此,我目前使用以下代码来实现这个功能:

#Get the lines that do not contain |NO|
LINES=`grep -v "|NO|" file`

for i in LINES
do
    sed "/$i/{s/$/|YES|/;}" file > temp
    mv temp file
done

上述方法是可行的,但是由于我的文件包含了超过40000行,运行时间大约需要3个小时。我认为花费这么长时间的原因是因为它需要搜索每一行并写入一个临时文件。是否存在更快的方法来实现这一点?

3个回答

4
这很简单:
sed '/NO/!s/$/|YES|/' filename

2
如果temp.txt是您的文件,请尝试以下操作:
awk '$0 !~ /NO/ {print $0 "|YES|"} $0 ~ /NO/ {print}' temp.txt

谢谢。这个很好用 :) 如果我不想在包含 NO 或 aaa 的行后添加 YES,我该如何修改上面的命令? - AKS
1
你应该使用 '|'(或)正则表达式字符,像这样awk '$0 !~ /NO|aaa/ {print $0 "|YES|"} $0 ~ /NO|aaa/ {print}' temp.txt顺便问一下,你的测试案例速度差异有多大? - Max
太好了,这正是我想要的。现在操作只需要不到一分钟就能执行完毕。我的以前的逻辑需要大约3个小时 :) 非常感谢。 - AKS

1

使用 awk 很简单。将下面的代码放到脚本中,然后使用 awk -f 脚本文件 > 临时文件 命令运行即可。

/\|NO\|/ { print; next; } # just print anything which contains |NO| and read next line
{ print $0 "|YES|"; } # For any other line (no pattern), print the line + |YES|

我不确定关于 awk 的正则表达式;如果它不起作用,请尝试删除第一个模式中的两个 \


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接