[英]Can linux sed efficiently replace entire line, with backreferences?
我經常使用sed
s/regex/replacement/g
命令,但我經常發現自己想用匹配部分的組合替換整行。 例如:
sed -rn 's/.*something([^ ]+) .*/\1/gp' log.txt
上面的輸出只是匹配行(模式空間的自動打印被-n
抑制)並且這些行被替換為跟隨something
的第一個空格分隔的標記。
但是,在處理大文件時,這會不必要地慢,因為開頭的.*
部分最初會匹配任何內容,一旦找到匹配項,匹配就會繼續尾隨的.*
。 但請注意這些.*
部分只需要替換整行,而不是匹配本身。
盡管沒有匹配整行,但有沒有辦法告訴sed
替換整行? 我嘗試使用“c”命令(替換行)但它似乎不使用反向引用:
sed -rn '/something([^ ]+) /c\ \1' log.txt
\1
不起作用。
編輯: grep -o 'something.*'
比使用.*
刪除行前綴的相應sed
命令快 6 倍。
首先,這是不可能匹配一行的一部分,並替換其中不匹配的部分。
用任何工具替換意味着消耗(將匹配的文本讀入緩沖區並推進正則表達式索引)與模式匹配的文本,並僅用提供的替換模式替換消耗的部分。
沒有被消費的東西不受正則表達式替換操作的影響。
因此,解決方案是確保匹配並使用要替換的文本的整個部分。
由於在模式結束前的任何地方使用.*
是一件代價高昂的事情(結尾處的.*
通常很快),你是對的,使用替代方法來提取所需的文本是個好主意。
在 Linux 中,可以使用 GNU grep
:
grep -Po 'something\K\S+' log.txt
在something
匹配並消耗something
文本的地方, \K
省略了匹配中的文本,而\S+
匹配一個或多個非空白字符。
此外,對於sed
,您可以在首次檢查特定模式時最大限度地減少.*
使用的影響:
sed -nE '/something[^ ]+ /s/.*something([^ ]+) .*/\1/p' file
可以更快地檢查something[^ ]+
部分,因此,只有匹配的行必須使用成本更高的模式進行處理。 請注意,如果很多行包含something
+一個或多個非空格+空格,這不會更好。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.