다음과 같은 디렉터리가 있습니다.
$ ls
Broad_hapmap3_r2_Affy6_cels_excluded.tgz DINGO.tgz GIGAS.tgz index.html IONIC.tgz passing_cels_sample_map.txt SCALE.tgz
CHEAP.tgz EPODE.tgz HOMOS.tgz index.html?C=M;O=A LOVED.tgz PICUL.tgz SHELF.tgz
CORER.tgz excluded_cels_md5.txt HUFFS.tgz index.html?C=N;O=D NIGHS.tgz POSIT.tgz SLOTH.tgz
CUPID.tgz excluded_cels_sample_map.txt HUSKS.tgz index.html?C=S;O=A passing_cels_md5.txt SAKES.tgz TESLA.tgz
Broad_hapmap3_r2_Affy6_cels_excluded.tgz를 제외하고 *.tgz 확장자와 일치하는 모든 파일의 압축을 풀기 위해 단일 명령을 사용하고 싶습니다.
저 할 수 있어요
ls *.tgz | xargs -n1 tar zxvf
모든 *tgz 파일을 제외하고 일부 파일을 제외하는 좋은 방법은 무엇입니까? 온라인에서 읽으면 이 상황에 대한 징후를 찾을 수 있지만 이는 과잉인 것 같습니다. 미리 감사드립니다.
부록: 파일을 제외하지 않는 문제에 대한 대안에도 관심이 있습니다.
답변1
zsh에서:
setopt extended_glob
for z in *.tgz~Broad_hapmap3_r2_Affy6_cels_excluded.tgz; do tar xzf $z; done
zsh의 또 다른 가능성:
setopt extended_glob
zargs -n 1 -- *.tgz~Broad_hapmap3_r2_Affy6_cels_excluded.tgz -- tar xzf
ksh에서(그러나 bash 또는 zsh는 및 모드를 지원하지 않으므로 제외):
for z in @(*.tgz&!(Broad_hapmap3_r2_Affy6_cels_excluded.tgz); do tar xzf "$z"; done
ksh의 또 다른 방법:
( FIGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
for z in *.tgz; do tar xzf "$z"; done )
배쉬에서:
( GLOB_IGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
for z in *.tgz; do tar xzf "$z"; done )
모든 셸에서:
for z in *.tgz; do
[ "$z" = Broad_hapmap3_r2_Affy6_cels_excluded.tgz ] || tar xzf "$z"
done
또 다른 해킹이 있습니다.
mv Broad_hapmap3_r2_Affy6_cels_excluded.tgz Broad_hapmap3_r2_Affy6_cels_excluded.tgz.not
for z in *.tgz; do tar xzf "$z"; done
mv Broad_hapmap3_r2_Affy6_cels_excluded.tgz.not Broad_hapmap3_r2_Affy6_cels_excluded.tgz
하위 디렉터리에 있는 파일에도 작업을 수행하려면 find가 자연스러운 도구입니다. 다음 재귀 예제에서는 Broad_hapmap3_r2_Affy6_cels_excluded.tgz
모든 하위 디렉터리에 이름이 지정된 파일을 제외합니다.
find . -name '*.tgz' -type f \
\! -name Broad_hapmap3_r2_Affy6_cels_excluded.tgz \
-exec tar xzf {} \;
**
zsh 또는 bash ≥4의 재귀 순회를 위해 모드에서 사용할 수 있습니다 . zsh에서:
setopt extended_glob
zargs -n 1 -- **/*.tgz~**/Broad_hapmap3_r2_Affy6_cels_excluded.tgz -- tar xzf
Bash ≥4에서:
shopt -s globstar
( GLOB_IGNORE=Broad_hapmap3_r2_Affy6_cels_excluded.tgz;
for z in **/*.tgz; do tar xzf "$z"; done )
재귀적으로 탐색하고 싶지 않다면 find를 사용할 수도 있지만 이것이 가장 편리한 방법은 아닙니다.
find *.tgz -type f \
\! -name Broad_hapmap3_r2_Affy6_cels_excluded.tgz \
-exec tar xzf {} \;
답변2
이와 같은 일회성 작업에 대해서는 무차별 대입을 사용합니다.
for f in *.tgz; do
[[ "$f" != "Broad_hapmap3_r2_Affy6_cels_excluded.tgz" ]] && tar zxvf "$f"
done
답변3
언제든지 다음과 같이 할 수 있습니다.
ls *.tgz | grep -v Broad_hapmap3_r2_Affy6_cels_excluded.tgz | xargs -n1 tar zxvf
그러나 누군가가 grep을 사용하지 않고 bash 쉘에서 직접 이 작업을 수행하는 보다 깔끔한 방법을 게시할지는 의문입니다.