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,則最終文件名只是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

相關內容