이것은 아마도 일반적이고 간단한 작업이지만 웹의 예제나 awk/sed/grep 매뉴얼에서는 이해할 수 없습니다.
따라서 시나리오는 다음과 같습니다.
- 입력 파일의 각 줄에 대해 여러 줄의 결과를 인쇄하는 내부 명령줄 도구가 있습니다.
- 500K 줄의 입력 파일이 있습니다.
- 도구의 출력에는 항상 "src:/some/directory"와 유사한 줄이 있습니다.
- 동일한 출력에 특정 문자열 "foo"가 있는 경우에만 이 행을 추출하고 싶습니다.
행 수는 이들 사이에 다를 수 있으므로 이 질문은 다소 관련이 있지만 정확히 내가 원하는 것은 아닙니다. awk를 사용하여 단일 파일에서 여러 정규식 일치
awk, sed 또는 grep을 사용하여 이 작업을 어떻게 수행할 수 있나요? Python을 사용하여 이 작업을 수행할 수 있지만 awk/sed를 배우고 싶고 이것이 좋은 예일 수 있기 때문에 그렇게 하고 싶지 않습니다.
이것이 내가 grep으로 시도한 것입니다.
tool -inputfile | if grep "foo"; then grep "src: " ; fi > result.txt
버퍼링 관련 이유로 인해 예상한 결과가 나오지 않습니다.
awk를 사용해 보세요:
tool -inputfile | awk '{for (i=1;i<NF;i++) {if(match($i, "foo")) print ??? }}' > result.txt
이 스크립트에 "src:"가 포함된 줄을 어떻게 인쇄할 수 있나요?
이 도구의 출력 예:
출력 1:
src: /usr/bin
param1: value1 value2
param2: "foo"
param3: "bar" "spam"
param4: "eggs" "spam" "spam"
출력 2:
src: /dev/null
param1: value1 value2
param2: "ham" "spam" "eggs"
그래서 두 경우 모두 첫 번째 경우인 src: /usr/bin만 추출하려고 했습니다.
답변1
src:
줄 시작 부분에 표시되고, foo
따옴표로 묶여 있고, 앞에 공백이 있고, 줄 앞에 콜론이 있어야 한다는 것을 알고 있는 경우 다음 을 사용하세요.
awk 'BEGIN{a=0} /^$/{if(a==1) print b; a=0} /:.* "foo"/{a=1} /^src:/{b=$0} END{if(a==1) print b}'
a
패턴이 foo
입력 블록에 나타나는지 여부를 기억하기 위해 변수를 사용 하고 행을 b
저장하기 위해 변수를 사용합니다. src:
처음에는 a
0으로 설정되어 있습니다. 빈 줄(예: )을 찾을 때마다 ^$
값을 확인하고 a
조건부로 인쇄한 b
후 재설정합니다 a
. "foo"
줄 시작 부분에서 앞에 콜론이 나타나면 이를 1로 설정 합니다 a
. 줄의 시작 부분에서 src:
( )를 만나면 이를 에 저장합니다 . 마지막으로 이면 다시 확인하고 , 그렇다면 인쇄합니다 .^
b
a == 1
b
답변2
간단한 awk
awk '/src/{a=$0}/foo/{b=1}b&&a{print a;exit}'
다른 형식이나 다른 방법으로 다른 곳에서 찾을 수 src
있는 경우foo
awk '/^src/{a=$0}/"foo"/{b=1}b&&a{print a;exit}'
foo가 항상 뒤에 오면src
awk '/^src/{a=$0}/"foo"/{print a;exit}'
파일에 여러 개의 src 블록이 있고 foo를 포함하는 각 블록을 인쇄하려는 경우
awk '/^src/{a=$0;b=0}/"foo"/{b=1}b&&a{print a;a=0}'