[英]SED: multiple patterns on the same line, how to match/parse first one
我有一個文件,里面有電話號碼數據,還有一些沒用的東西。 我正在嘗試解析數字,當只有 1 個電話號碼/線路時,這不是問題。 但是當我有多個數字時,sed 匹配最后一個(即使它到處都說它應該只匹配第一個模式?),我無法得到其他數字。
我的數據.txt:
bla bla bla NUM:09011111111 bla bla bla bla NUM:08022222222 bla bla bla
當我解析數據時,我的想法是首先刪除第一個電話號碼前面的所有“初始”“bla bla bla”(因此我搜索第一次出現的 'NUM:'),然后刪除所有內容在電話號碼之后,並獲取號碼。 之后,我想從剩余的字符串中解析下一次出現。
所以現在當我嘗試 sed 時,我總是得到最后一個數字:
>sed 's/.*NUM://' data.txt
08022222222 bla bla bla
>
主要是我想了解我對 SED 的理解有什么問題。 當然歡迎更有效的建議! 我的 sed 命令不是說,用 ''(空)替換 'NUM:' 之前的所有內容嗎? 為什么它總是匹配最后一次出現?
謝謝!
這可能對你有用:
echo "bla bla bla NUM:09011111111 bla bla bla bla NUM:08022222222 bla bla bla" |
sed 's/NUM:/\n&/g;s/[^\n]*\n\(NUM:[0-9]*\)[^\n]*/\1 /g;s/.$//'
NUM:09011111111 NUM:08022222222
您遇到的問題是理解.*
是貪婪的,即它匹配最長的匹配而不是第一個匹配。 通過在我們感興趣的字符串( NUM:...
)前面放置一個唯一字符( \\n
sed 將其用作行分隔符,因此它不能存在於行中)並刪除所有不是該唯一字符的內容[^\\n]*
后跟唯一字符\\n
,我們有效地將字符串拆分為可管理的部分。
正如您現在所知, sed
表達式是貪婪的,據我所知不能成為非貪婪的。
到目前為止尚未提出的兩種替代方案是僅使用其他工具進行此類匹配/提取。
您可以使用perl
作為帶有-pe
參數的 sed 的替代品。 它支持?
非貪婪修飾符:
$ perl -pe 's/.*?NUM://' data.txt
09011111111 bla bla bla bla NUM:08022222222 bla bla bla
您可以使用 GNU grep 的-o
選項來僅獲取與正則表達式匹配的數據位:
$ egrep -o 'NUM:[0-9]*' data.txt
NUM:09011111111
NUM:08022222222
如果數字由NUM:
后面的NUM:
定義:
sed -n -e 's/$/\n/' -e ':begin' \
-e 's/\(NUM:[0-9][0-9]*\)\(.*\)\n\(.*\)/\2\n\3 \1/' \
-e 'tbegin' -e 's/.*\n //' -e '/NUM/p'
它的作用是:
\\n
作為標記。也可以反過來做,首先刪除沒有數字的行:
sed -e '/NUM/!d' -e 's/$/\n/' -e ':begin' \
-e 's/\(NUM:[0-9][0-9]*\)\(.*\)\n\(.*\)/\2\n\3 \1/' \
-e 'tbegin' -e 's/.*\n //'
sed -E 's/(-y)|(-f)|(\+incdir\+)/\n&/g' abcfile > cdeop
其中 abcfile 將作為示例 -y / -f / +incdir+ patterns ,當模式匹配時,它將在其之前插入新行。
您可以使用此模式:
sed -r 's/^(.*NUM:)(.*NUM:.*)$/\2/'
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.