2014-02-08 159 views
0

嗨我正在尋找通過文件進行搜索,並輸出與下面的正則表達式相匹配的行的值與刪除匹配的文本,我不需要它輸出到一個文件。這是我目前使用的,它是輸出所需的文本,但多次:使用多個sed命令

#!/bin/sh 

for file in *; do 
sed -e 's/^owner //g;p;!d ; s/^admin //g;p;!d ; s/^loc //g;p;!d ; s/^ser //g;p;!d' $file 
done 

的首選格式將是這樣的,所以我可以擁有控制權發生了什麼其間:

for file in *; do 
    sed 's/^owner //g;p' $file | head -1 
    sed 's/^admin //g;p' $file | head -1 
    sed '/^loc //g;p' $file | head -1 
    sed '/^ser //g;p' $file | head -1 
done 

一個示例的輸入文件是以下各項:

owner sys group 
admin guy 
loc Q-30934 
ser 18r9723 
comment noisy fan is something 

和所需的輸出如下:

sys group 
guy 
Q-30934 
18r9723 

回答

0

您正在給sedp(用於打印)命令幾次。它每次打印整行。除非您告知不要使用-n選項,否則sed將在最後打印該行。

您還多次給出!d命令。

在添加多版本版本後進行編輯:而不是使用head -q,只需使用-n即可避免打印您不想要的行。甚至使用q(退出)在打印完您想要的位後停止處理。

例如:

sed -n '/^owner/{ s///gp; q; }' $file 

{}組的取代和退出命令一起,使它們都執行當且僅當所述模式匹配。在開始使用地址模式後,您可以將其保留在s命令之外。因此,該命令是短期的:

sed -n '/^owner/{ s/^owner //gp; q; }' $file 
+0

感謝您的回答,我試過這個:sed's/^ owner // g; q'$ file,它在第一個sed命令之後工作,但之後的sed命令只輸出文件的第一行而不合並 –

+0

這幾乎是正確的。我已經爲我的答案添加了一個示例。編輯完成後,它會在一兩分鐘後出現。簡而言之,s和q命令是獨立的,所以q在第一行執行。你需要用括號將它們組合在一起。 –

+0

非常感謝你! –

0

我建議:

sed -n -e '/^owner/{ s///; p; }' \ 
     -e '/^admin/{ s///; p; }' \ 
     -e '/^loc/ { s///; p; }' \ 
     -e '/^ser/ { s///; p; }' \ 
    * 

sed是完全能夠讀取許多文件,所以循環控制是不必要的(你是不是每個文件做例如I/O重定向),並且在sed命令的其餘部分(即自己的*)之後列出文件是合理的。如果你有一個更現代版的sed(如GNU sed),可以將圖案合併成一條線:

sed -r -n -e '/^(owner|admin|loc|ser)/{ s///; p; }' * 
+0

不幸的是,這會導致誤報,因爲每個文件可能有不止一次出現所需的字符串。 – potong

1

這可能會爲工作(GNU SED):

sed '0,/^owner /{//s///p};0,/^admin /{//s///p};0,/^loc /{//s///p};0,/^ser /{//s///p}' file 

創建一系列切換開關,爲每個所需的字符串創建一個切換開關。每個字符串只在整個文件中應用一次,即只打印每個字符串的第一次出現。

一種替代,並且根據文件大小可能較快的方法:

sed -rn '1{x;s/^/owner admin loc ser /;x};/^(owner |admin |loc |ser)/{G;/^(owner |admin |loc |ser)(.*\n.*)\1/!b;s//\2/;P;/\n$/q;s/.*\n//;h}' file 

此製備物與所需的字符串保留空間。對於只包含所需字符串的行,追加保留空間並檢查當前行是否需要修改。將所需的字符串與保存空間中的相同字符串進行匹配。如果該線已經出現,則該比賽將失敗並且該線可以被忽略。如果該行尚未修改,則將從當前行中刪除所需的字符串,然後打印行的前半部分。如果在剩下的一半行中沒有字符串出現,則該過程結束並可以退出。否則,請移除字符串的前半部分,並用所需的字符串替換保留空間。