在 tar 命令中使用 -C 選項時如何使用 glob/萬用字元?
我的目錄結構如下:
/home/workspace/build/
/home/workspace/js/jai.1.js /home/workspace/js/jai.2.js /home/workspace/js/jai.3.js /home/workspace/js/jai.4.js
我想對目錄到目錄中前綴為jai的所有js文件進行****tar處理。
/home/workspace/js/``/home/workspace/build/
假設創建的 tar 文件的名稱是bundle.tar.gz
所以 bundle.tar.gz應該包含以下文件
jai.1.js jai.2.js jai.3.js jai.4.js
我想使用
tar
命令而不是將文件複製到目標然後對其進行 tar 來實現此目的。編輯
我想從
destination
目錄中提取它,即/home/workspace/build/
(cd ../js && pax -w jai.*.js) | gzip > bundle.tar.gz
會這樣做(或者如果您有命令則
pax -w
替換為)。關鍵是使用子shell只為/更改目前目錄。tar cf -``tar``pax``tar
一些
tar
實現(tar
是一個非常不可移植的命令,這就是引入 POSIX 的原因pax
)有一個-C
選項可以使它更改文件集合的目錄,但不更改文件輸出。它們通常還支持自行z
呼叫gzip
或在內部實現 gzip 壓縮的選項。但是,例如:
tar czf bundle.tar.gz -C ../js jai.*.js
不起作用,因為它
jai.*.js
由目前目錄未更改的 shell 擴展。使用zsh
,您可以執行以下操作:tar czf bundle.tar.gz -C ../js ../js/jai.*.js(:t)
修飾符
:t
獲取glob 生成的文件的尾部(基本名稱)的位置。使用
pax
,您還可以執行以下操作:pax -'s|.*/||' -w -- ../js/jai.*.js | gzip > bundle.tar.gz
但請注意,去除前導路徑組件的替換也將適用於符號連結的目標(某些
tar
實現具有類似的選項,您可以指定是否要翻譯這些文件),並且如果這些jail.*.js
文件中的任何一個也會給出不同的結果是目錄類型並包含更多文件。使用 libarchive
bsdtar
,您還可以執行以下操作:bsdtar zcf bundle.tar.gz -C ../js --include=. --include='jai.*.js' .
GNU
tar
沒有--include
,--exclude
所以你可以這樣做:tar zcf bundle.tar.gz -C ../js --exclude='*[^s.]' \ --exclude='*?.' \ --exclude='*[^j]s' \ --exclude='*[^.]js' .
(那些會添加一個條目
.
)與
star
:star czf bundle.tar.gz -C ../js 'pat=jai.*.js' .
(將包括
jai.foo/bar.js
但不包括目錄中的不匹配文件jail.*.js
)star czf bundle.tar.gz -C ../js 'pat=jai.#[^/].js{%!/*}' .
(where
#<expr>
is like<expr>*
in EREs and{%!/*}
like(/.*)?
(%
is nothing and!
is OR)) 與(cd ../js && tar czf - jai.*.js) > bundle.tar.gz
. 它仍然會爬取整個目錄結構,只選擇頂層的文件。對於較新的版本,您還可以使用
-find
. 因此,對於我們的等效項(cd ...)
,它不會爬入不必要的目錄但仍包含目錄中的所有文件jai.*.js
:star czf bundle.tar.gz C=../js -find . \ \( \( -name '*.js' -o -path '*/*' -o -name . \) -o ! -prune \) ! -name .
雖然更有可能,但您實際上想要:
star czf bundle.tar.gz C=../js \ -find . -maxdepth 1 -name 'jai.*.js' -type f
那是只歸檔
jai.*.js
正常文件,並且只在頂層歸檔,zsh
你也可以這樣做:(cd ../js && pax -w -- jai.*.js(.)) | gzip > bundle.tar.gz
(
(.)
作為限制為正常文件的全域限定符)。