我想删除包含单词“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
你可以告诉我,我是一个newb在这:(
sed -e '/test/{/test@/!d;}'
第一种模式与包含“测试”的行匹配; 第二个模式删除行,除非它们匹配“test @”。
测试数据文件:
aaaa bbbtestbbb ccctest@ccc test! dddd
输出:
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