BEGIN: 소싱을 통해 실행될 때 간단한 awk 스크립트에서 명령을 찾을 수 없습니다.

BEGIN: 소싱을 통해 실행될 때 간단한 awk 스크립트에서 명령을 찾을 수 없습니다.

저는 awk오늘 배우고 있는데 가장 간단한 스크립트를 성공적으로 작동시킬 수 없습니다.

#!/usr/bin/env -S awk -f
BEGIN { }
{ }
END { }

이 출력BEGIN: command not found

심지어

#!/usr/bin/env -S awk -f
{}

이 출력{}: command not found

실행할 때 $ /usr/bin/env -S awk -f기본 출력을 표시하는 awk 실행 파일이 있습니다 .

$ awk --versionnixos 19.09의 awk 버전 5.0.1이라고 말합니다 .

/usr/bin/envnixos 파일은 전통적인 FHS 디렉터리 계층 구조를 따르지 않기 때문에 nixos를 사용해야 합니다 .

나는 명백한 것을 놓치고 있다고 생각하지만 awk 튜토리얼과 SO 질문을 봐도 아직 어떤 단서도 얻지 못했습니다.

편집: 스크립트를 시작하는 데 사용하는 명령줄

ls -l | . testawk.sh

답변1

조달은아니 똑같다구현하다. 특히 소싱에는 현재 셸에서 실행할 수 있는 명령 목록이 필요합니다. 다음은 bash에서 가져온 것입니다 help ..

.: .파일 이름[매개변수]

현재 셸의 파일에 있는 명령을 실행합니다.

현재 셸의 FILENAME에서 명령을 읽고 실행합니다. $PATH의 항목은 FILENAME이 포함된 디렉터리를 찾는 데 사용됩니다. ARGUMENTS가 제공되면 FILENAME을 실행할 때 위치 인수가 됩니다.

따라서 를 실행하면 . file쉘은 파일을 읽고 찾은 모든 명령을 실행합니다. 그러나 이는 shebang 줄이 무시되고 일반 주석으로 처리됨을 의미합니다. 따라서 awk가 아닌 쉘이 BEGIN.

이를 방지하려면 스크립트를 가져오는 대신 스크립트를 실행해야 합니다. 만약 어떤 이유로든 당신이 단지~ 해야 하다이를 얻으려면 스크립트에 awk 명령을 작성하십시오.

awk '
BEGIN { }
{ }
END { }'

그럼, 당신은 할 수 있습니다

ls | . ./a.awk 

왜 당신이 이것을하고 싶어하는지 정말로 알 수는 없지만.


그건 그렇고, .기본적으로 (또는 bash에서) source파일에서 파일 이름을 찾는다는 것을 알아야 합니다. $PATH따라서 실행 . foo하고 foo현재 디렉터리에 파일이 있고 의 foo임의 디렉터리에 파일이 있으면 $PATH가져올 파일은 $PATH현재 디렉터리의 파일이 아니라 에 있는 파일입니다. 이를 방지하려면 소싱할 때 항상 전체 경로를 사용하십시오 . ./foo.

답변2

Shebang을 사용하여 awk를 호출하지 마십시오. 이렇게 하면 스크립트 매개변수를 셸에서 수행해야 하는 부분과 awk에서 수행해야 하는 부분으로 분리하고 awk 매개변수를 awk 변수 할당에서 분리하는 기능이 사라지기 때문입니다. 다음과 같이 스크립트를 작성하세요.

#!/usr/bin/env bash

/usr/bin/env awk '
BEGIN { }
{ }
END { }
' "$@"

때로는 awk 변수 설정과 같은 작업을 수행하기 위해 이를 수정하고 싶을 때도 있습니다.

#!/usr/bin/env bash

rs="$1"
fs="$2"
shift 2

/usr/bin/env awk -v RS="$rs" -F "$fs" '
BEGIN { }
{ }
END { }
' "$@"

이는 위와 같이 간단해야 하지만 shebang을 사용하여 awk를 호출하는 경우에는 이를 수행할 수 없습니다.

답변3

AdminBee의 의견에서 언급했듯이 스크립트 호출 방식(콘텐츠 가져오기)이 잘못되었습니다.

올바른 접근 방식은 다음과 같습니다.

ls -l | ./test.awk

또는 더 간단하게는 해당 #!라인에 의존하지 않고 다음과 같습니다.

ls -l | awk -f ./test.awk

관련 정보