하나의 명령을 사용하여 여러 tar 파일을 개별적으로 압축 해제하는 방법은 무엇입니까?

하나의 명령을 사용하여 여러 tar 파일을 개별적으로 압축 해제하는 방법은 무엇입니까?

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-0null로 끝나는 매개변수를 읽기 위한 비표준 옵션을 지원하는 경우.

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합니다 .xargsxargs-P

관련 정보