2017-09-06 94 views
0

假設多行文本文件file如果滿足不同行上的兩個條件,則刪除行

$cat file 
foo bar baz 
foo bar baz qux 
foo bar baz quux # Line to be deleted 
foo bar quux 

我希望刪除所有那些fullfill兩個條件線:(a)該行包含關鍵字「QUUX」,和(b)的線是立即由包含一個線preceeded關鍵字「qux」。

$cat file | sought_command 
foo bar baz 
foo bar baz qux 
foo bar quux 

我很茫然作爲UNIX工具可以應用到這樣的雙重條件(可能AWK,但我不確定),並希望建議。

編輯1: 一旦被通知awk是使用工具和在考慮的任務進一步,我要找專門爲代碼,可以很容易地被修改,使得條件(b)可以反轉(即, 「(b)如果有必要,該行不會立即包含關鍵字'qux'」的行)。

+1

無需不知所措:S /老/新=> sed和克/ RE/P => grep和別的(例如。)=> awk。現在 - 你在尋找字符串還是正則表達式比較以及部分或全部匹配? –

回答

0

這可能是你要尋找的依賴,如果你想字符串或正則表達式比較和部分或全部的比賽上。

1)刪除行,如果它包含QUUX和前述之一包含qux:

$ awk '!(/quux/ && p~/qux/); {p=$0}' file 
foo bar baz 
foo bar baz qux 
foo bar quux 

2)刪除行,如果它包含QUUX和前一個不包含qux:

awk '!(/quux/ && p!~/qux/); {p=$0}' file 

,如果你喜歡,以避免雙重否定,布爾代數可以減少到:

awk '!/quux/ || p~/qux/; {p=$0}' file 

您喜歡的任何複合條件只需執行& & -ing和/或|| -ing和/或否定$ 0上的測試(隱含在/.../中)和p。

+0

我明白了。所以'awk'畢竟是工具。是的,字符串比較是我正在尋找的。感謝你及時的答覆。 –

+0

短期隨訪:如果我想將條件(b)更改爲「該行是** NOT **,緊接着包含關鍵字'qux'的行,則該怎麼辦?」。用awk單行程來實現會很簡單嗎? –

+1

這裏沒有任何答案進行字符串比較,它們都與部分匹配進行正則表達式比較。如果你匹配的文本('quux'和'qux')可以包含regexp元字符(例如'q。* x'),那麼字符串/ regexp的區別很重要。是否允許部分匹配(例如'qux'匹配'fooquxbar'?)可能更相關。是的,任何改變都是微不足道的:'awk'!(/ quux/&& p!〜/ qux /); {p = $ 0}'文件'布爾代數可以簡化爲'awk'!/ quux/|| P〜/ qux /; {p = $ 0}'文件'。 –

0

AWK腳本,將你想要做什麼:

$ cat tst.awk 
/quux/ && p { p=/qux/; next } 
{ p=/qux/ } 
{ print } 

與輸入:

$ cat input.txt 
foo bar baz qux 
foo bar baz quux qux 
foo bar baz quux 
foo bar quux 

給出:

$ awk -f tst.awk input.txt 
foo bar baz qux 
foo bar quux 

後續問題是每當它連接時刪除一行tains'quux'和前面的行確實是而不是包含'qux'。一個簡單的否定p就是要做的。

cat tst2.awk 
/quux/ && !p { p=/qux/; next } 
{ p=/qux/ } 
{ print } 

與輸入:

$ cat del.txt 
foo bar baz qux 
foo bar baz quux qux 
foo bar baz quux 
foo bar quux  # to be deleted 

給出:

awk -f tst2.awk del.txt 
foo bar baz qux 
foo bar baz quux qux 
foo bar baz quux 
+0

@MarcLambrichs我剛剛編輯我的問題,使其更具體。你的代碼如何修改以允許條件(b)的逆轉? –

0

您可以通過以下方式使用awk

awk '$4 ~/qux/ || $4 !~/quux/' file 

foo bar baz 
foo bar baz qux 
foo bar quux 
相關問題