輸入
AA XXX Y1Y ZZZ GG dhz
rr (AAAa) XXX Y2Y ZZZ TT GGGG UU
輸出
Y1Y
Y2Y
輸入行可能會有所不同。 Y1Y 可以是任何內容,例如:Y1Y、Y2Y、Y1T 等。
問:如何使用 awk 或 sed 或 grep 來取得輸出? (或者有更好的工具嗎?)
更新(問題):為什麼當有“.”時它不起作用在Y1Y?
[user@notebook ~] echo 'XXX Y1Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
Y1Y
[user@notebook ~] echo 'XXX Y1.Y ZZZ' | grep -Po "(?<=XXX )(\w+)(?= ZZZ)"
[user@notebook ~]
答案1
您可以使用grep
它提供的 PCRE 工具來執行此操作:
$ grep -Po "(?<=XXX )\S+(?= ZZZ)" data.txt
Y1Y
Y2Y
細節
此解決方案利用了PCRE的lookbehind和lookahead功能,可以匹配固定長度的字串。
上面的內容是查看每個的後面,\w+
看看它是否是,XXX
以及每個的頭部,\w+
看看它是否是ZZZ
。如果是,那麼就配對了。開關-o
告訴grep
它只列印匹配項,即\w+
.
後續,可以用sed來做嗎?
我不認為這個問題可以用 來解決sed
。我認為有兩種方法。
- 將潛在的匹配保存在側面變數中,如果遇到 ZZZ,則列印它們
- s/XXX ..我們的字串.. ZZZ/ ..我們的字串../
第一似乎是相當大量的工作,所以我什至不會嘗試它。以下是方法 2 所發生的情況。
$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU
所以它可以很好地找到匹配項,但對於不匹配的行它不會做任何事情。可能有一種方法可以指示sed
刪除這些行,在這種情況下,這將是替代解決方案。