$n
AWK에서 명령 대체를 수행하고 AWK 표기법을 사용하여 대체 명령의 필드를 참조할 수 있는 방법이 있습니까 ?
예를 들어
find | awk '/txt$/ {nl = $(wc -l $NF); print nl}'
.txt
위의 내용을 통해 각 파일의 줄 수를 인쇄하고 싶습니다 . 대신 실제로 다음과 동일한 출력을 반환합니다.
find | awk '/txt$/ {print}'
질문 1:awk에서 명령 대체를 수행하는 방법이 있습니까?
질문 2:위의 첫 번째 주문이 자동으로 실패하고 파일 이름만 인쇄하는 이유는 무엇입니까?
위의 내용은 예시일 뿐이라는 점을 참고하시기 바랍니다. 다른 방법으로 각 파일의 줄 수를 인쇄하는 방법을 묻는 것이 아닙니다. 예를 들어for f in $(find -iname \*.txt); do wc -l $f; done
문제는 특히 AWK 프로그램에서 명령 대체를 활용하는 방법에 관한 것입니다.
답변1
첫째, 면책조항:출력을 구문 분석하지 마십시오 find
. 다음 코드는 명령이 Awk의 입력 조각에서 작동할 수 있도록 명령 대체를 Awk 스크립트에 통합하는 방법을 설명하기 위한 것입니다.
도착하다실제로wc -l
발견된 각 파일에 대해 줄 수( )를 계산하려면 find
(이는 예시 사용 사례임) 다음을 사용하세요.
find . -type f -name '*txt' -exec wc -l {} +
그러나 귀하가 요청한 질문에 대답하려면 다음을 수행하십시오.
1분기
귀하의 질문 1에 답변하려면:
Q1: awk에서 명령 대체를 수행할 수 있는 방법이 있습니까?
물론 다음과 같은 방법이 있습니다 man awk
.
Command | getline [var] 출력을 $0 또는 var(위와 같이) 및 RT로 파이프하여 명령을 실행합니다.
그래서 (인용문을 보세요!!):
find . | awk '/txt$/{"wc -l <\"" $NF "\"|cut -f1" | getline(nl); print(nl)}'
생성된 문자열과 그에 따라 실행되는 명령은 다음과 같습니다.
wc -l <file
인쇄를 피하기 위해 wc
.
글쎄, 나는 해당 명령에 필요한 파일 "닫기"를 피했습니다(일부 파일에는 안전하지만 기술적으로는 올바르지 않음). 실제로 다음을 수행해야 합니다.
find . | awk '/txt$/{
comm="wc -l <\"" $NF "\" | cut -f1"
comm | getline nl;
close (comm);
print nl
}'
이는 이전 awk 버전에서도 작동합니다. print dot을 사용하지 마십시오.
dot는 디렉토리이고 wc는 이를 사용할 수 없기 때문에 코드가 실패하게 됩니다..
find .
또는 포인트 값을 사용하지 마세요.
find . | awk '/txt$/ && $NF!="." { comm="wc -l <\"" $NF "\" | cut -f1"
comm | getline nl;
close (comm);
print nl
}'
이것을 한 줄의 코드로 변환할 수는 있지만 보기 흉해 보입니다.
2분기
두 번째 질문은 다음과 같습니다.
질문 2: 위의 첫 번째 주문이 자동으로 실패하고 파일 이름만 인쇄되는 이유는 무엇입니까?
awk는 쉘 명령을 올바르게 구문 분석할 수 없기 때문입니다. 명령을 다음과 같이 이해합니다.
nl = $(wc -l $NF)
nl --> variable
$ --> pointer to a field
wc --> variable (that has zero value here)
- --> minus sign
l --> variable (that has a null string)
$ --> Pointer to a field
NF --> Last field
그러면 l $NF
null과 the의 연결이 됩니다.텍스트las 필드(파일 이름) 내. 이 유형의 텍스트를 숫자 변수로 확장하는 값은 0입니다.
awk의 경우 다음과 같습니다.
nl = $( wc -l $NF)
nl = $ ( 0 - 0 )
이는 $0
입력의 전체 줄이 되며(위의 간단한 찾기의 경우) 파일 이름만 됩니다.
따라서 위의 모든 내용은 파일 이름(기술적으로는 전체 줄)만 인쇄합니다.
답변2
"weak quotes"
대신 스크립트 내에서 'strong quotes'
하위 쉘 확장을 사용하십시오 awk
. 그러나 예제에서 그렇게 하는 것은 특별히 가치 있는 구현이 아닙니다. 또한 매우 추악해 보입니다.
$ awk "END { print \"$(echo hello)\"} " < /dev/null
hello