디렉토리 구조가 없는 Tar 파일 목록

디렉토리 구조가 없는 Tar 파일 목록

내가 이렇게 한다고 가정해보자:

tar cvf allfiles.tar $(<mylist.txt)

그리고내 목록.txt다음을 포함합니다:

/tmp/lib1
/tmp/path2/lib2
/path3/lib3

tarball에만 포함되도록 파일을 압축하는 방법

lib1
lib2
lib3

디렉토리 구조가 전혀 없나요?


일반적으로 권장되는 -C옵션(--directory인용하다,인용하다), 하지만 디렉터리가 여러 개 있으므로 작동하지 않습니다. 또한 --xform고정된 패턴이 필요한 것 같습니다(인용하다)우리는이 없습니다.

답변1

이 매개변수는 매우 강력한 대체 표현식을 --xform원하는 만큼 취합니다 . sed귀하의 경우 끝까지 모든 것과 일치하는 패턴을 사용한 /다음 무엇이든 바꾸십시오.

tar cvf allfiles.tar --xform='s|.*/||' $(<mylist.txt)

--show-transformed-names새 이름을 보려면 추가하세요 .

이 대체는 명령줄에 지정된 파일 이름뿐만 아니라 모든 파일 이름에 적용됩니다. 따라서 예를 들어 파일이 하나 있고 /a/b/c목록에 만 지정되어 있는 경우 /a최종 파일 이름은 that c이 아니라 that 입니다 b/c. 귀하의 경우와 같이 언제든지 더 명확하고 정확한 대체 목록을 제공할 수 있습니다.

--xform='s|^tmp/path2/||;s|^tmp/||;s|^path3/||'

첫 번째 문자는 /tar에 의해 제거되므로(tar를 사용하지 않는 한 -P) 위의 표현식에서는 해당 문자가 손실됩니다. 또한 가장 긴 일치 항목이 먼저 수행되도록 디렉터리 목록을 정렬해야 합니다. 그렇지 않으면 제거되었기 tmp/path2/때문에 일치 항목이 없습니다 . tmp/하지만 다음과 같이 이 목록을 자동으로 만들 수 있습니다.

--xform="$(sed <mylist.txt 's|[^/]*$||; s|^/||; s:.*:s|^&||;:' | sort | tr -d '\n')"

답변2

GNU를 사용하면 언제 어디서나 사용할 tar수 있으며 즉시 작동합니다.-C

$ tree
.
├── 1
│   └── aaa
├── 2
│   └── bbb
└── 3
    └── ccc



# Caveat: the directory change is always relative to directory tar is using *at
# that time*, so the following doesn't work:
$ tar -cf foo.tar -C 1 aaa -C 2 bbb -C 3 ccc  
tar: 2: Cannot open: No such file or directory
tar: Error is not recoverable: exiting now

$ tar -cf foo.tar -C 1 aaa -C ../2 bbb -C ../3 ccc

$ tar tf foo.tar
aaa
bbb
ccc


# You can avoid the special case for the first directory by always specifying
# an absolute path:
$ tar -cf foo.tar -C $(pwd)/1 aaa -C $(pwd)/2 bbb -C $(pwd)/3 ccc



# Now let's create that automatically from your file:
$ cat mylist.txt
/tmp/1/aaa
/tmp/2/bbb
/tmp/3/ccc

$ while read -r line; do printf '-C %s %s ' $(dirname "$line") $(basename "$line") ; done < mylist.txt
-C /tmp/1 aaa -C /tmp/2 bbb -C /tmp/3 ccc 

# That looks about right. Let's use it in our tar command:
$ tar -cvf foo.tar $(while read -r line; do printf '-C %s %s ' $(dirname "$line") $(basename "$line") ; done < mylist.txt)
aaa
bbb
ccc

관련 정보