구문 분석해야 하는 복잡한 로그가 있습니다. 내가 원하는 것은 문자열을 찾는 것입니다시간, 일치하는 행에서 열 5를 가져온 다음 열 5가 문자열과 일치하는 다른 모든 행을 가져옵니다.시간.
입력 예
a b c d 31 1
a b c d 31 H
a b c d 31 2
a b c d 32 1
a b d d 32 2
a b c d 33 1
a b c d 33 H
a b c d 33 2
예상 출력
a b c d 31 1
a b c d 31 H
a b c d 31 2
a b c d 33 1
a b c d 33 H
a b c d 33 2
따라서 두 개의 별도 스크립트를 만들어 이 작업을 수행할 수 있습니다.
script1 | xargs -n1 | script2
스크립트 1검색 문자열시간를 누른 다음 다섯 번째 열을 인쇄합니다.
cat logfile | grep 'H' | awk '{print $5}'
스크립트 2그런 다음 열 5가 첫 번째 스크립트의 출력과 일치하는 로그 파일의 다른 모든 줄을 인쇄합니다.
cat logfile | awk -v var="$1" '$5 == var'
입력 파일, 로그 파일을 변수로 만들어 스크립트에서 $1을 사용한 다음 script logfile
. 일반적으로 이를 수행하는 올바른 방법은 무엇입니까? 나는 bash 스크립팅을 처음 접했기 때문에 평균이라고 말합니다.
내가 가진 두 가지 문제는 첫째, 첫 번째 스크립트(즉, 로그 파일)의 $1이 내가 awk로 파이프하는 두 번째 스크립트(즉, 첫 번째 스크립트의 출력 번호)의 $1과 다릅니다. 둘째, xargs -n1
bash 스크립트에서 사용할 수 있는 해당 항목을 찾을 수 없습니다 .
답변1
두 번째는 awk
두 개의 입력을 차례로 읽습니다. 첫 번째에서 파이프된 출력을 읽은 다음 awk
파일 자체에서 파이프된 출력을 읽습니다. 두 번째 입력의 시작을 식별하는 한 가지 방법은 NR
(질소현재 투입량오른쪽전체 기록)이 더 이상 일치하지 않습니다 FNR
(현재에프ile의 레코드 번호). -
FILE arg는 awk
슬레이브에게 stdin
(를 통해) 알리는 것을 의미합니다.관로, 이 경우).
awk '$6=="H"{print $5}' "$1" |
awk 'NR==FNR{k[$1];next}
$5 in k{print}' - "$1"
두 번째 입력을 식별하는 위의 방법은 일반적으로 사용되지만 첫 번째 입력에서 아무것도 읽지 않으면 예상/원하는 대로 동작하지 않습니다. 이 작업의 요구 사항의 경우 첫 번째 입력이 아무것도 제공하지 않아도 상관 없습니다. 논리는 인덱스 값 목록을 NR=FNR
작성하는 곳(예: 기본 파일에서)을 결코 지나치지 않지만 이를 사용하여 아무 작업도 수행하지 않습니다. 따라서 스크립트는 빈 입력으로 파이프되지만 이는 단지 혼란 때문입니다. 특정 논리가 부작용으로 사용됩니다.k
$1
gawk
그러나 GNU awk()에는 현재 파일/파이프를 결정하는 안정적인 방법이 있습니다 . 명령줄 인수에는 특별한 변형이 있습니다 FILE
:"...var=value 형식의 인수는 var 변수에 값을 할당합니다. 이는 파일을 전혀 지정하지 않습니다."- 바라보다:기타 명령줄 매개변수 이러한 배치변수=값args가 중요합니다 - 특정 파일에 필요한 값은 명령줄에 배치되어야 합니다앞으로관련 파일 – 후속 조치변수=값awk
이전 파일/파이프를 완전히 읽을 때까지 적용되지 않습니다.
여기있어변수=값버전.
gawk '$6=="H"{print $5}' "$1" |
gawk 'fn==1{k[$1];next}
$5 in k{print}' fn=1 - fn=2 "$1"
출력(두 스크립트 버전 모두 동일)
a b c d 31 1
a b c d 31 H
a b c d 31 2
a b c d 33 1
a b c d 33 H
a b c d 33 2