如何用 sed 替換字串中的所有內容(除了 % 和直接緊跟其後的任何數字)?意思是,除了字串之外的所有內容,例如:
%1
%1000
%55
ETC。
給定這種形式的字串:
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
我只想得到%3
和%4
零件。數字最多可達999
.
答案1
$ sed 's/^.*\(%[0-9]\+\).*$/\1/' input
假設一行至多包含一個這些%123
標記,且每一行都包含這樣一個標記。
元\( \)
字元標記一個匹配組 - 然後透過\1
反向引用在替換中引用該匹配組。^
/$
匹配行的開頭/結尾。
否則,您可以預先過濾輸入,例如:
$ grep '%[0-9]\+' input | sed 's/^.*\(%[0-9]\+\).*$/\1/'
(當並非所有行都包含這樣的標記時)
另一種變體:
$ sed 's/\(%[0-9]\+\)/\n\1\n/g' | grep '%[0-9]'
(當一行可能包含多個這些標記時)
以下是直接在每個標記之前和之後插入的換行符號 - 在管道的第一部分中。然後該grep
部分刪除所有非%123
標記行。
答案2
grep -o
在這種情況下你最好使用:
grep -oP '\B%[0-9]{1,3}\b' inputfile
假設您的版本grep
支援 Perl 相容的正規表示式 ( -P
)。否則:
grep -o '\B%[0-9]\{1,3\}\b' inputfile
使用 GNU sed
,可以將空格音譯為換行符並獲得所需的行:
sed 'y/ /\n/' inputfile | sed '/^%[0-9]\{1,\}/!d'
答案3
使用時sed
幾乎總是建議:
/address then/s/earch/replace/
有兩個原因。第一個是多行速度/addressing/
更快 - 它僅針對尋找匹配,並且不必只選擇行的一部分進行編輯,因此它可以更快地縮小結果範圍。
第二個原因是您可以對同一地址執行多個編輯操作 - 這使事情變得更加容易。
當然,在這種情況下,僅給出您顯示的數據,這沒有實際差異。不過,這就是我會做你問的事情的方式:
sed '/^[^%]*\|[^0-9]*$/s///g' <<\DATA
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
DATA
#OUTPUT
%3
%4
它只是選擇所有字符非-%從行首開始的字符以及所有字符非數位的地址中行尾的字符,然後用s///
- 刪除它們,就是這樣。
在當前的形式下,如果您向其提供行,它可能會以意想不到的方式破壞數據不是包含一個%digit
組合 - 這就是為什麼尋址很重要。如果我們稍微改變一下:
/%[0-9]/s/[^%]*\|[^0-9]*$//g
變得更安全和快點。
答案4
我的解決方案不使用 sed,而是使用具有擴展正則表達式和僅匹配選項的 grep。
$ cat file
1: [18x14] [history 1/2000, 268 bytes] %3
2: [18x14] [history 1/2000, 268 bytes] %4 (active)
$ cat file | grep -Eo '%[0-9]+'
%3
%4
在這種情況下使用 grep 比使用 sed 更簡單。