删除文件中匹配一个字符串但不匹配另一个字符串的行 - SED、BASH?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6530896/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Delete line in file matching one string but not matching another - SED, BASH?
提问by WonderOatmeal
I want to remove all lines in a file which contain the word "test" but if that line contains "test@" then I do not want to delete it.
我想删除文件中包含“test”一词的所有行,但如果该行包含“test@”,那么我不想删除它。
There is probably some funky way of doing this with sed but I am struggling, I tried to write a bash loop using sed but this is probably stupid.
使用 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
As you can tell, I'm a newb at this :(
如您所知,我是这方面的新手:(
回答by Jonathan Leffler
sed -e '/test/{/test@/!d;}'
The first pattern matches the lines containing 'test'; the second pattern deletes lines unless they match 'test@'.
第一个模式匹配包含“test”的行;第二个模式删除行,除非它们匹配 'test@'。
Tested on the data file:
在数据文件上测试:
aaaa
bbbtestbbb
ccctest@ccc
test!
dddd
Output:
输出:
aaaa
ccctest@ccc
dddd
That seems to meet your requirements.
这似乎满足您的要求。
回答by WonderOatmeal
Use grep:
使用grep:
grep -v 'test[^@]' infile
Usually grepprints matching lines but -vtells it to print non-matching lines.
通常grep打印匹配的行,但-v告诉它打印不匹配的行。
The regular expression matches any occurance of "test" that is followed by anything but a '@'. This is fine if you don't have to expect "test" coming up at the end of a line. If that is the case, use
正则表达式匹配任何出现的“test”,后跟除“@”之外的任何内容。如果您不必期望在一行的末尾出现“测试”,这很好。如果是这种情况,请使用
grep -E -v 'test([^@]|$)'
I don't think it is worth going into why your solution does not work, because it is broken in so many ways.
我认为没有必要深入研究为什么您的解决方案不起作用,因为它在很多方面都被破坏了。
回答by Frost
If you flip your question around a bit, it becomes:
如果你稍微翻转一下你的问题,它就会变成:
How do I filter out all lines from a file that either contains the string 'test@' or does not contain the string 'test'.
如何从包含字符串“test@”或不包含字符串“test”的文件中过滤掉所有行。
This can for example be done in awk like this:
例如,这可以在 awk 中完成,如下所示:
awk '!/foo/ || /foo@/' testfile
Jonathan's answeralso works, I just wanted to give you an alternate version.
乔纳森的回答也有效,我只是想给你一个替代版本。
回答by nando
There is no need for a tmp file if you use ed!
如果您使用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

