상수 이웃이 있는 열만 출력하는 방법은 무엇입니까?

상수 이웃이 있는 열만 출력하는 방법은 무엇입니까?

입력하다

AA XXX Y1Y ZZZ GG dhz
rr (AAAa) XXX Y2Y ZZZ TT GGGG UU

산출

Y1Y
Y2Y

입력 라인은 다를 수 있습니다. Y1Y 이전의 XXX와 Y1Y 이후의 ZZZ만 상수입니다(이와 같이 XXX와 ZZZ의 이웃입니다). 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의 뒤돌아보기 및 미리보기 기능을 활용하여 고정 길이 문자열을 일치시킵니다.

위의 내용은 각각의 뒷면을 보고 \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, 이 경우 이것이 대체 솔루션이 될 수 있습니다.

관련 정보