입력하다
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
. 저는 두 가지 방법이 있다고 생각합니다.
- 잠재적인 일치 항목을 측면 변수에 저장하고 ZZZ가 발견되면 인쇄합니다.
- s/XXX ..우리의 문자열..ZZZ/ ..우리의 문자열../
첫 번째는 꽤 손이 많이 가는 것 같아서 시도조차 하지 않겠습니다. 방법 2에서는 다음과 같은 일이 발생합니다.
$ sed 's/.*XXX \(.*\) ZZZ.*/\1/' data.txt
Y1Y
Y2Y
AAAa YXX Y2Y ZZZ TT GGGG UU
따라서 일치하는 항목을 찾는 것은 잘 작동하지만 일치하지 않는 행에 대해서는 아무 작업도 수행하지 않습니다. 이러한 행을 삭제하도록 지시하는 방법이 있을 수 있으며 sed
, 이 경우 이것이 대체 솔루션이 될 수 있습니다.