删除文件中匹配一个字符串但不匹配另一个字符串的行 - SED,BASH?

时间:2011-06-30 06:41:11

标签: linux bash unix sed sh

我想删除文件中包含单词“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

正如你所知,我是一个新手:(

4 个答案:

答案 0 :(得分:10)

sed -e '/test/{/test@/!d;}'

第一个模式匹配包含'test'的行;第二种模式删除行,除非它们匹配'test @'。

测试数据文件:

aaaa
bbbtestbbb
ccctest@ccc
test!
dddd

输出:

aaaa
ccctest@ccc
dddd

这似乎符合您的要求。

答案 1 :(得分:4)

使用grep

grep -v 'test[^@]' infile

通常grep会打印匹配的行,但-v会告诉它打印不匹配的行。

正则表达式匹配任何“test”的出现,后跟除“@”之外的任何内容。如果您不必期望在一行结束时出现“测试”,那么这很好。如果是这种情况,请使用

grep -E -v 'test([^@]|$)'

我认为不值得研究为什么你的解决方案不起作用,因为它在很多方面都被打破了。

答案 2 :(得分:1)

如果你稍微翻一下问题,那就变成了:

如何过滤掉包含字符串'test @'或不包含字符串'test'的文件中的所有行。

例如,这可以在awk中完成:

awk '!/foo/ || /foo@/' testfile

Jonathan's answer也有效,我只是想给你一个替代版本。

答案 3 :(得分:1)

如果您使用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
相关问题