나는 이렇게 tar를 사용한다.
tar -cjpvf a.tar "$pattern1" "$pattern2"
문제는 패턴1과 패턴2가 때때로 동일한 파일과 일치하지만 tar가 이러한 중복 항목을 필터링하지 않는 것 같습니다.
예를 들어 다음 예에서는 아카이브에 두 개의 중복 항목을 추가합니다.
%> tar -cjpvf a.tar /etc/passwd /etc/passwd
%> tar -xvf a.tar
etc/passwd
etc/passwd
어떻게 필터링할 수 있나요?
답변1
pattern1
및가 쉘 와일드카드 패턴 인 경우 pattern2
또는 패턴을 사용할 수 있습니다.
tar -cjpvf a.tar @($pattern1|$pattern2)
이를 위해서는 ksh, bash 또는 zsh가 필요합니다. Bash에서는 패턴 구문을 shopt -s extglob
활성화하려면 실행 해야 합니다 . @(…)
zsh에서는 setopt ksh_glob
먼저 실행하거나(또한 zsh에 변수에 문자열 대신 패턴이 포함되어 있음을 알려줌 @($~pattern1|$~pattern2)
) 기본 구문을 사용해야 합니다 ($~pattern1|$~pattern2)
.
답변2
구문 분석된 출력이 마음에 드는 경우 ls
(모든 파일 이름에 문자나 와일드카드가 포함되지 않거나 $IFS
로 시작한다고 가정함 -
):
tar -cjpvf a.tar $(ls -d1 <pattern1> <pattern2> | sort | uniq)
또는
tar -cjpvf a.tar $(ls -d1 <pattern1> <pattern2> | sort -u)
출력을 구문 분석하는 데 익숙하지 않은 경우 ls
올바른 방법은 다음을 사용하는 것입니다 (GNU 또는 호환 가능하다고 find
가정 ).tar
find -maxdepth 1 \( -name <pattern1> -o -name <pattern2> \) -print0 \
| xargs -0 tar -cjpvf a.tar
(이것은 파일 목록이 tar
한 번의 호출만 실행할 수 있을 만큼 작다고 가정합니다. 또한 find
숨겨진 파일은 기본적으로 무시되지 않습니다.)
답변3
순서가 중요한 경우. 예를 들어, 아카이브 foo*
와 파일을 모두 원하고 파일이 아카이브의 첫 번째( 두 번은 아님) 에 나타나기를 *.txt
원하는 경우입니다 . IOW, 이 순서대로:foo*
foo.txt
foo.a
foo.b
foo.txt
foo.z
a.txt
b.txt
z.txt
그리고 zsh
:
files=(./foo*(N) ./*.txt(N))
(($#files)) && tar jcf file.tar.bz2 ${(u)files}
그리고 tcsh
:
set -f files = (./foo* ./*.txt) && tar jcf file.tar.gz2 $files:q
마지막 인지 확인하려면 *.txt
( foo.a
foo.b
foo.z
a.txt
b.txt
foo.txt
z.txt
순서대로):
그리고 zsh
:
files=(./foo*(N) ./*.txt(N))
(($#files)) && tar jcf file.tar.bz2 ${(uOa)${(Oa)files}}
( Oa
파라미터 확장 플래그로 배열의 순서를 반대로 합니다.)
그리고 tcsh
:
set -l files = (./foo* ./*.txt) && tar jcf file.tar.gz2 $files:q