aa.tar, bb.tar, cc.tar,...와 같은 tar 파일이 많이 있습니다.
aa/, bb/, cc/...와 같은 자체 디렉토리에 추출하고 싶습니다.
나는 이것을 시도했습니다 :
ls | xargs -n1 -I {} tar -xvf {} -C `basename {} .tar`
이것은 작동하지 않습니다. {}는 전체 tar 파일 이름으로 사용하거나 .tar
.
어떻게 작동하게 할 수 있나요?
답변1
실행 시 {}
명령 대체(호출)에는 사용할 수 없습니다.basename
앞으로전화도 xargs
했어요. 이는 디렉토리를 각 아카이브에 대해 tar
(문자 그대로) 명명된 디렉토리 로 변경하려는 시도가 이루어짐을 의미합니다.{}
for
예를 들어 루프를 사용하면 필요하지 않습니다 xargs
.
for t in *.tar ; do
bn="$(basename "$t" .tar)"
mkdir -p "$bn"
tar -xvf "$t" -C "$bn"
done
또한보십시오:왜아니요구문 분석 ls
(및 수행 방법)?
답변2
명령이 작동하지 않는 이유는 명령 대체(백틱으로 작성한 비트)가 xargs
시작 전에 한 번 수행되기 때문입니다.
로 태그를 지정하셨기 때문에 를 기반으로 솔루션을 xargs
제공할 것이라고 생각했습니다 .xargs
먼저 단일 아카이브의 압축을 풀려면 tar
다음을 사용할 수 있습니다.
dir=${archive%.tar}
mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"
... $archive
아카이브의 파일 이름이 포함되어 있고 tar
아카이브가 일반(압축되지 않음)이라고 가정합니다.
분명히 이것을 반복 할 수 있습니다
for archive in *.tar; do
dir=${archive%.tar}
mkdir -- "$dir" && tar -x -f "$archive" -C "$dir"
done
xargs
그러나 이는 여러 명령을 병렬로 실행하는 것과 같은 일부 일반적인(비표준이지만) 기능을 사용할 수 없게 합니다 .
초기 명령을 한 번에 4개씩 실행하려면 tar
아카이브 이름을 xargs
표준 입력에 입력해야 합니다.
우리는 할 수있어
printf '%s\n' *.tar | xargs ...
이는 분명히 아카이브 이름에 새 줄이 포함되어 있지 않다고 가정하지만 다음을 사용하여 이 문제를 해결할 수 있습니다.
printf '%s\0' *.tar | xargs -0 ...
구현에서 xargs
-0
null로 끝나는 매개변수를 읽기 위한 비표준 옵션을 지원하는 경우.
from 에서 압축 풀기를 실행하려면 xargs
가장 쉬운 방법은 하위 쉘에서 실행하는 것입니다 sh -c
.
printf '%s\0' *.tar |
xargs -0 -P 4 -I {} sh -c 'dir=${1%.tar}; mkdir -- "$dir" && tar -x -f "$1" -C "$dir"' sh {}
sh -c
쉘 스크립트 에서는 $1
초기 명령과 동일하며 $archive
스크립트는 각 아카이브에 대해 한 번 실행됩니다. 구현에서 지원하는 경우 옵션은 네 가지 추출 옵션을 병렬로 실행 -P 4
합니다 .xargs
xargs
-P