我像这样使用焦油,
tar -cjpvf a.tar "$pattern1" "$pattern2"
问题是pattern1和pattern2有时匹配同一个文件,但tar似乎没有过滤这些重复项。
例如,以下示例在存档中添加两个重复条目
%> tar -cjpvf a.tar /etc/passwd /etc/passwd
%> tar -xvf a.tar
etc/passwd
etc/passwd
我怎样才能过滤掉它们?
答案1
如果pattern1
和pattern2
是 shell 通配符模式,那么您可以使用 or 模式。
tar -cjpvf a.tar @($pattern1|$pattern2)
这需要 ksh、bash 或 zsh。在 bash 中,您需要shopt -s extglob
先运行才能激活@(…)
模式语法。在zsh中,需要setopt ksh_glob
先运行(并且还要告诉zsh变量包含模式而不是字符串,所以@($~pattern1|$~pattern2)
),或者使用原生语法($~pattern1|$~pattern2)
。
答案2
如果您觉得解析 的输出很舒服ls
(这里假设所有文件名都不包含 字符$IFS
或通配符或以 开头-
):
tar -cjpvf a.tar $(ls -d1 <pattern1> <pattern2> | sort | uniq)
或者
tar -cjpvf a.tar $(ls -d1 <pattern1> <pattern2> | sort -u)
如果您不习惯解析 的输出ls
,正确的方法是使用find
(这里假设 GNUtar
或兼容):
find -maxdepth 1 \( -name <pattern1> -o -name <pattern2> \) -print0 \
| xargs -0 tar -cjpvf a.tar
(这里假设文件列表足够小,只tar
运行一次调用。另请注意,find
默认情况下不会忽略隐藏文件)。
答案3
如果顺序很重要。例如,如果您想要存档foo*
和*.txt
文件,并且希望foo*
文件首先出现在存档中(但foo.txt
不包含两次)。 IOW,按foo.a
foo.b
foo.txt
foo.z
a.txt
b.txt
z.txt
这个顺序:
和zsh
:
files=(./foo*(N) ./*.txt(N))
(($#files)) && tar jcf file.tar.bz2 ${(u)files}
和tcsh
:
set -f files = (./foo* ./*.txt) && tar jcf file.tar.gz2 $files:q
如果您想确保它们*.txt
是最后的(foo.a
foo.b
foo.z
a.txt
b.txt
foo.txt
z.txt
按顺序):
和zsh
:
files=(./foo*(N) ./*.txt(N))
(($#files)) && tar jcf file.tar.bz2 ${(uOa)${(Oa)files}}
(Oa
作为参数扩展标志,反转数组的顺序)
和tcsh
:
set -l files = (./foo* ./*.txt) && tar jcf file.tar.gz2 $files:q