[英]Using multiple sed commands
嗨,我正在搜索文件,並輸出與以下正則表達式匹配的行的值,並刪除了匹配的文本,我不需要將其輸出到文件中。 這是我當前正在使用的,並且正在輸出所需的文本,但是多次輸出:
#!/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
您多次給sed
p
(用於打印)命令。 每次打印整行。 而且,除非您使用-n
選項告訴它不這樣做,否則sed
仍將在最后打印該行。
您還多次給出!d
命令。
添加多版本版本后進行了編輯:不用head -q
,而是使用-n
避免打印不需要的行。 甚至在打印完所需的位后,使用q
(退出)停止處理。
例如:
sed -n '/^owner / { s///gp; q; }' $file
{}
將replace和quit命令組合在一起,以便僅在模式匹配時才執行它們。 在開頭使用地址中的模式后,可以將其保留在s
命令之外。 因此,該命令的縮寫為:
sed -n '/^owner / { s/^owner //gp; q; }' $file
我建議:
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; }' *
這可能適用於(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
這將為保留空間准備所需的字符串。 僅對於包含所需字符串的那些行,追加保留空間並檢查是否需要修改當前行。 將所需的字符串與保留空間中的相同字符串匹配。 如果該行已經出現,則匹配將失敗,並且可以忽略該行。 如果該行尚未修改,則從當前行中刪除所需的字符串,然后打印該行的前半部分。 如果行的其余部分中沒有出現字符串,則該過程結束,可以退出。 否則,請取下琴弦的前半部分,並用取下的琴弦替換存放空間。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.