在 tar 命令中使用 -C 选项时如何使用通配符/通配符?

Pra*_*yal 2 tar utilities wildcards command

我的目录结构如下:

/home/workspace/build/
Run Code Online (Sandbox Code Playgroud)
/home/workspace/js/jai.1.js
/home/workspace/js/jai.2.js
/home/workspace/js/jai.3.js
/home/workspace/js/jai.4.js
Run Code Online (Sandbox Code Playgroud)

我想焦油所有的js文件,其前缀是JAI是在/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
Run Code Online (Sandbox Code Playgroud)

我想使用tar命令来实现这一点,而不是将文件复制到目的地,然后对其进行 tar 处理。

编辑

我想从destination目录中解压缩它,即/home/workspace/build/

Sté*_*las 5

(cd ../js && pax -w jai.*.js) | gzip > bundle.tar.gz
Run Code Online (Sandbox Code Playgroud)

会这样做(如果您有命令pax -wtar cf -则替换为tar)。关键是通过使用子shell只为pax/更改当前目录tar

一些tar实现(tar是一个非常不可移植的命令,这就是为什么引入 POSIX 的原因pax)有一个-C选项可以使它更改文件集合的目录,而不是文件输出的目录。那些通常也支持自己z调用gzip或在内部实现 gzip 压缩的选项。

但是,诸如:

tar czf bundle.tar.gz -C ../js jai.*.js
Run Code Online (Sandbox Code Playgroud)

不起作用,因为它jai.*.js被当前目录未更改的外壳程序扩展。使用zsh,您可以执行以下操作:

tar czf bundle.tar.gz -C ../js ../js/jai.*.js(:t)
Run Code Online (Sandbox Code Playgroud)

:t修改得到尾巴由水珠所产生的文件(基名)。

使用pax,您还可以执行以下操作:

pax -'s|.*/||' -w -- ../js/jai.*.js | gzip > bundle.tar.gz
Run Code Online (Sandbox Code Playgroud)

但请注意,去除前导路径组件的替换也适用于符号链接的目标(某些tar实现具有类似的选项,您可以在其中指定是否要翻译这些jail.*.js文件),并且如果这些文件中的任何一个,也会给出不同的结果属于目录类型并包含更多文件。

使用 libarchive bsdtar,您还可以执行以下操作:

bsdtar zcf bundle.tar.gz -C ../js --include=. --include='jai.*.js' .
Run Code Online (Sandbox Code Playgroud)

GNUtar没有--includeby --exclude,所以你可以这样做:

tar zcf bundle.tar.gz -C ../js --exclude='*[^s.]' \
                               --exclude='*?.' \
                               --exclude='*[^j]s' \
                               --exclude='*[^.]js' .
Run Code Online (Sandbox Code Playgroud)

(那些会添加一个条目.

star

star czf bundle.tar.gz -C ../js 'pat=jai.*.js' .
Run Code Online (Sandbox Code Playgroud)

jai.foo/bar.js虽然将包括,而不是jail.*.js目录中的不匹配文件)

star czf bundle.tar.gz -C ../js 'pat=jai.#[^/].js{%!/*}' .
Run Code Online (Sandbox Code Playgroud)

(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 .
Run Code Online (Sandbox Code Playgroud)

虽然更有可能,但您实际上想要:

star czf bundle.tar.gz C=../js \
  -find . -maxdepth 1 -name 'jai.*.js' -type f
Run Code Online (Sandbox Code Playgroud)

那是仅存档jai.*.js 常规文件,并且仅在顶级文件中存档,zsh您也可以这样做:

(cd ../js && pax -w -- jai.*.js(.)) | gzip > bundle.tar.gz
Run Code Online (Sandbox Code Playgroud)

(.)作为限制为常规文件的glob 限定符)。