awk의 명령 대체

awk의 명령 대체

$nAWK에서 명령 대체를 수행하고 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 $NFnull과 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

관련 정보