나는 비슷한 게시물에서 가져온 다음 스니펫을 사용하고 있습니다.https://unix.stackexchange.com/a/101273/212793- 파일에서 파일 이름 가져오기 tar.gz
:
tar tzf "archive.tar.gz" | awk -F/ '{ if($NF != "") print $NF }'
내 경우에는 특정 파일이 하나만 필요하므로 다음과 같은 것을 사용합니다.
tar tzf "archive.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' | grep -e "^..*my-file-name\\.ext$"
문제는 내 .tar.gz
것이 크고 파일이 많이 포함되어 있다는 것입니다. 그러나 각각은 시작 부분에 유사한 "해시"가 추가되어 있습니다(따라서 ^..*
내 grep'd 정규식의 일부임).
따라서 이러한 파일은 다음과 같습니다.
- 4b77e4e1_file-a.ext
- 4b77e4e1_file-b.ext
- 4b77e4e1_file-c.ext
# ect.
tar tzf "archive.tar.gz" | awk -F/ '{ if($NF != "") print $NF }'
모든 파일() 스트림 출력을 가져오는 명령을 확인했습니다.
아이디어는 스트림을 "중단"한 다음 첫 번째 해시 부분을 추출할 수 있으면 파일의 전체 내용을 반복할 필요 없이 궁극적으로 필요한 파일 이름을 만들 수 있다는 것입니다 .tar.gz
.
그래서 내 질문은 전체 명령이 완료될 때까지 기다리지 않고(몇 분 소요) 첫 번째 출력에서 어떻게 "중단"하고 결과를 파악하여 궁극적으로 원하는 파일 이름을 얻을 수 있는지입니다 .awk
편집하다: 첫 번째 결과 이후 단순히 ing을 실행해도 실행 시간이 변경되지 않기 tar
때문에 실제로 중단하고 싶은 것 같습니다 .exit
답변1
다음과 같은 것을 시도해보세요
tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /my-filename$/ {print $NF ; exit }'
또는
tar tzf "archive.tar.gz" | awk -F/ 'substr($NF,4,11) == "my-filename" {print $NF ; exit }'
(여기서 4와 11은 실제 파일 이름과 일치합니다).
답변2
파이프라인의 프로그램 중 하나가 종료되면 왼쪽에 있는 프로그램도 종료됩니다. 작동 방식은 다음과 같습니다.
- 에서 종료
foo | bar
합니다bar
. - 프로세스를 종료하면 파이프의 읽기 끝이 닫힙니다.
foo
파이프에 쓰려고 하면 SIGPIPE 신호를 받습니다.foo
사망 한.
이는 foo
SIGPIPE에 대한 보호가 없다고 가정합니다. 프로그램은 이를 수행할 수 있지만 일반적인 명령줄 프로그램은 이를 수행할 수 없습니다.
하나의 일치만 원하기 때문에 awk는 관심 있는 라인을 찾는 즉시 종료됩니다.
tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
또는 (여기서 별로 유리하지 않음)
tar tzf "archive.tar.gz" | sed -n '/[^/]my-file-name\.ext$/ {s!.*/!!; q}'
또는 awk와 별도로 grep의 보다 정교한 접근 방식을 고수하십시오.
tar tzf "archive.tar.gz" | awk -F/ '{ if($NF != "") print $NF }' | grep -e "^..*my-file-name\\.ext$" | head -n 1
판독기에서 종료하면 tar
다음에 파이프에 쓸 때 종료되므로 시간이 걸릴 수 있습니다.출력 버퍼. (파이프에 두 개 이상의 프로세스가 있는 경우 각 프로세스가 SIGPIPE를 수신하는 데 약간의 지연이 있기 때문에 특히 오랜 시간이 걸립니다.) awk
종료 후 find
아카이브를 읽고 다음 항목을 채우는 데 시간이 걸립니다. buffer with filename 은 마지막으로 버퍼에 쓰기를 시도하고 SIGPIPE에 의해 종료됩니다. 이 응용 프로그램의 경우 출력을 위해 tar를 라인 버퍼링으로 전환하는 것이 더 빠를 수 있습니다.stdbuf
:
stdbuf -oL tar tzf "archive.tar.gz" | awk -F/ '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
대안으로, awk가 종료될 때 tar 프로그램을 종료하도록 설정할 수 있지만 이는 더 복잡합니다.
sh -m 'tar tzf "archive.tar.gz" | {
awk -F/ "$0";
kill -TERM -$$;
}' '$NF ~ /.my-file-name\.ext$/ {print $NF; exit}'
[ $? -eq 143 ]
답변3
무언가를 인쇄한 후 AWK에 종료하도록 지시할 수 있습니다.
awk -F/ '$NF != "" { print $NF; exit }'
특정 파일 이름을 찾고 있으므로:
awk -F/ '/my-file-name\.ext$/ && $NF != "" { print $NF; exit }'
그러면 테스트가 $NF
중복됩니다.
awk -F/ '/my-file-name\.ext$/ { print $NF; exit }'