디렉터리 구조 없이 파일 목록을 Tar로 만듭니다.

디렉터리 구조 없이 파일 목록을 Tar로 만듭니다.

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

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

그리고mylist.txt다음을 포함합니다:

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

tarball에 파일이 포함되도록 파일을 tar하는 방법

lib1
lib2
lib3

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


일반적으로 다음 옵션 -C--directory권장합니다(심판,심판), 그러나 디렉토리가 여러 개 있으므로 작동하지 않습니다. 또한 --xform고정된 패턴이 필요한 것 같습니다(심판) 우리에게는 없습니다.

답변1

논증은 매우 강력한 대체 표현을 --xform원하는 만큼 취합니다 . sed귀하의 경우 마지막까지 모든 것과 일치하는 패턴을 사용 /하고 아무것도 바꾸지 마십시오.

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

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

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

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

이니셜은 /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

관련 정보