tar를 사용하여 중복된 파일 이름 필터링

tar를 사용하여 중복된 파일 이름 필터링

나는 이렇게 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.txtfoo.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

관련 정보