如何只輸出具有恆定鄰居的列?

如何只輸出具有恆定鄰居的列?

輸入

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。我認為有兩種方法。

  1. 將潛在的匹配保存在側面變數中,如果遇到 ZZZ,則列印它們
  2. s/XXX ..我們的字串.. ZZZ/ ..我們的字串../

第一似乎是相當大量的工作,所以我什至不會嘗試它。以下是方法 2 所發生的情況。

$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt 
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU

所以它可以很好地找到匹配項,但對於不匹配的行它不會做任何事情。可能有一種方法可以指示sed刪除這些行,在這種情況下,這將是替代解決方案。

相關內容