[英]Delete line in file matching one string but not matching another - SED, BASH?
我想删除文件中包含“test”一词的所有行,但如果该行包含“test@”,那么我不想删除它。
使用 sed 可能有一些时髦的方法,但我很挣扎,我尝试使用 sed 编写一个 bash 循环,但这可能很愚蠢。
filetest=/tmp/filetest
filetest_tmp=/tmp/filetest.tmp<
line_num=0
while read line; do
line_num=$(($line_num+1))
if [[ $line == *rootsh* ]] && [[ $line != *root@* ]]
then
sed -e "${line_num}"'d' $filetest >> $filetest_tmp
fi
done < $filetest
cp $syslog_tmp $filetest
如您所知,我是这方面的新手:(
sed -e '/test/{/test@/!d;}'
第一个模式匹配包含 'test' 的行; 第二个模式删除行,除非它们匹配'test@'。
在数据文件上测试:
aaaa
bbbtestbbb
ccctest@ccc
test!
dddd
Output:
aaaa
ccctest@ccc
dddd
这似乎符合您的要求。
使用grep
:
grep -v 'test[^@]' infile
通常grep
打印匹配的行,但-v
告诉它打印不匹配的行。
正则表达式匹配任何出现的“test”,其后跟除“@”之外的任何内容。 如果您不必期望“测试”出现在行尾,这很好。 如果是这种情况,请使用
grep -E -v 'test([^@]|$)'
我认为不值得探讨为什么您的解决方案不起作用,因为它在很多方面都被破坏了。
如果你稍微翻转一下你的问题,它会变成:
如何从包含字符串“test@”或不包含字符串“test”的文件中过滤掉所有行。
例如,这可以在 awk 中完成,如下所示:
awk '!/foo/ || /foo@/' testfile
乔纳森的回答也有效,我只是想给你一个替代版本。
如果您使用ed
,则不需要 tmp 文件!
# cf. http://wiki.bash-hackers.org/howto/edit-ed
cat <<-'EOF' | ed -s file
H
,g/test$/d
,g/test[^@]/d
wq
EOF
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.