
我有一個文件,其中有幾行包含國家/地區名稱的信息,如下所示。
$cat country.txt
max_china_clean_foo
man_india_raw_bar
max_us_clean_bax
max_uk_raw_bar
max_canada_raw_foo
max_au_clean_bar
我只想從此文件中提取國家/地區名稱。我目前正在使用下面的程式碼在 for 循環中提取國家/地區名稱
val=${val#*_}
val=${val%_clean*}
echo $val
但產生的輸出只有china, us
和au
國家/地區名稱,因此我必須重複類似的程式碼並進行少量修改才能提取其餘國家/地區,如下所示
val=${val#*_}
val=${val%_raw*}
echo $val
clean
我知道,這不是一種清晰的編碼方式,因此需要您的幫助從所有包含或raw
字串的行中提取國家/地區名稱。
有沒有辦法使用 awk 或 sed 提取具有兩個匹配鍵的所有國家/地區名稱?我的輸出應該是這樣的
china
india
us
uk
canada
au
答案1
在這裡,你可以這樣做:
cut -d _ -f 2 < country.txt
或者,如果輸入可能包含沒有_
字元的行:
awk -F _ 'NF >= 2 {print $2}' < country.txt
如果國家/地區名稱可能包含_
字符,並且您希望返回該行的第一次_
出現和第一次出現之間_raw
或_clean
之後的部分,您可以執行以下操作:
perl -ne 'print $1 if s/^[^_]*_(.*?)_(clean|raw)/' < country.txt
或使用 GNU grep
:
grep -Po '^[^_]*_\K.*?(?=_clean|_raw)' < country.txt
-P
(前提是已grep
使用 PCRE 支援建構),正規表示式是與 perl 相容的正規表示式。在這些正規表示式中,\K
重置匹配字串的開頭,並且(?=...)
是一個前瞻運算符,也就是說,它會查找字串的其餘部分是否匹配...
,而該部分是否包含在匹配部分中。-o
使grep
輸出匹配的部分,因此這裡它打印與.*?
上面匹配的內容,這是 的非貪婪等價物.*
,即0 個或多個字符的序列,盡可能短,在本例中遵循0 個或多個下劃線的序列([^_]*
) 位於行 ( ) 的開頭,^
後面跟著下劃線,並假設其後跟_raw
或_clean
。
有了pcregrep
,你還可以這樣寫:
pcregrep -o1 '^[^_]*_(.*?)_(clean|raw)'
使用-o1
,它會列印與第一個 相符的部分(...)
。
答案2
這是 awk 風格的方式
awk -F'_' '/clean|raw/{ print $2}'