2011-06-30 180 views
5

我想刪除文件中包含單詞「test」的所有行,但如果該行包含「test @」,那麼我不想刪除它。刪除文件中匹配一個字符串但不匹配另一個字符串的行 - SED,BASH?

可能有一些這樣做與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 != *[email protected]* ]] 
       then 
       sed -e "${line_num}"'d' $filetest >> $filetest_tmp 
     fi 
done < $filetest 
cp $syslog_tmp $filetest 

正如你所知道的,我在這個對於新手:(

+3

請不要在您的示例中使用「root」時在描述中使用「test」。請在示例中使用「testsh」/「test @」時,不要在描述中使用「test」/「test @」。撰寫問題時請小心。請? – hop

回答

10
sed -e '/test/{/[email protected]/!d;}' 

的第一圖案包含「測試」的線相匹配;第二個模式刪除線,除非它們匹配「測試@ 」

測試上的數據文件:

aaaa 
bbbtestbbb 
[email protected] 
test! 
dddd 

輸出:

aaaa 
[email protected] 
dddd 

這似乎符合您的要求。

4

使用grep

grep -v 'test[^@]' infile 

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

正則表達式匹配任何「test」後面除了「@」之外的任何事件。如果您不必期望在測試結束時出現「測試」,這很好。如果是這樣的話,使用

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

我不認爲這是值得一去到爲什麼你的解決方案不起作用,因爲它在很多方面打破。

1

如果你翻車了一下週圍你的問題,就變成:

如何從,要麼包含字符串「測試@」或不包含字符串「測試」文件過濾掉所有行。

例如,這可以在AWK就像這樣:

awk '!/foo/ || /[email protected]/' testfile 

Jonathan's answer也適用,我只是想給你一個替代版本。

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 
相關問題