我正在创建文件夹树的备份,并尝试按路径智能地排除大量文件。我仔细阅读了 zip 手册页,以查看文件排除选项是否-x 'pattern'
按文件名匹配文件路径。这不是很清楚,但它似乎该选项使 zip 在定位要包含的文件时按文件路径匹配。或选项-R
的描述中没有提供这样的模糊提示。我对的测试似乎表明它确实根据文件路径而不是文件名匹配来排除文件:-i
-x
-x 'pattern'
# Bash command line example
$ mkdir -p TstDir/tstHHHdir
$ touch TstDir/tstHHHdir/file.c
$ zip -r test.zip TstDir -x '*HHH*'
updating: TstDir/ (stored 0%)
我不太愿意根据有限的试验进行猜测,因为很容易出错或以某种方式曲解。
-r
无论如何,能否明确地说出按文件路径匹配是否是 zip 选项的默认行为?如果是这样,那么和选项之间有什么区别-R
?
答案1
-x
下面通过实证测试来测试 zip 的选项、-d
、
-r
和的模式匹配行为-R
。
# Create test folders for -x and -d
mkdir -p TstDir/tstAAAsubdir \
TstDir/tstBBBsubdir \
TstDir/tstCCCsubdir \
TstDir/tstDDDsubdir \
TstDir/tstEEEsubdir
# Create test files for -x and -d
touch TstDir/tstAAAsubdir/fileA.c \
TstDir/tstBBBsubdir/fileB.c \
TstDir/tstCCCsubdir/fileC.c \
TstDir/tstDDDsubdir/fileD.c \
TstDir/tstEEEsubdir/fileE.c
# -x option matches by path
zip -rDy test.zip TstDir -x '*AAA*' '*BBB*'
adding: TstDir/tstCCCsubdir/fileC.c (stored 0%)
adding: TstDir/tstDDDsubdir/fileD.c (stored 0%)
adding: TstDir/tstEEEsubdir/fileE.c (stored 0%)
# -d option matches by path
zip -d test.zip '*CCC*' '*DDD*'
deleting: TstDir/tstCCCsubdir/fileC.c
deleting: TstDir/tstDDDsubdir/fileD.c
#=================================================
# Create test folders for -r and -R
mkdir -p TestDir/testAAAdir \
TestDir/testBBBdir
# Create test files for -r and -R
touch TestDir/testAAAdir/File.b \
TestDir/testBBBdir/File.b \
TestDir/testAAAdir/File.c \
TestDir/testBBBdir/File.c
#-------------------------------------------------
# -r matches by file path
zip -r test.zip '*AAA*.c'
updating: TestDir/testAAAdir/File.c (stored 0%)
#-------------------------------------------------
# -R doesn't match file path
zip -R test.zip '*AAA*.c'
zip error: Nothing to do! (test.zip)
#-------------------------------------------------
# The well-known behaviour of -r to descend into
# the file/path specified, recursively zipping
# up files
zip -r test.zip TestDir
updating: TestDir/testAAAdir/File.c (stored 0%)
updating: TestDir/testBBBdir/File.c (stored 0%)
adding: TestDir/ (stored 0%)
adding: TestDir/testAAAdir/ (stored 0%)
adding: TestDir/testAAAdir/File.b (stored 0%)
adding: TestDir/testBBBdir/ (stored 0%)
adding: TestDir/testBBBdir/File.b (stored 0%)
#-------------------------------------------------
# -R didn't match by path above, but does
# recursively descend into the specified folder and
# matches encountered files by file name
zip -R test.zip TestDir '*.c'
updating: TestDir/testAAAdir/File.c (stored 0%)
updating: TestDir/testBBBdir/File.c (stored 0%)
#-------------------------------------------------
# Even if the path pattern exists in the folder
# into which zip descends, the -R option *still*
# doesn't match by path -- at least, not treating
# the file separator as an ordinary file name
# character that matchable by "*"
zip -R test.zip TestDir '*AAA*.c'
zip error: Nothing to do! (test.zip)
#-------------------------------------------------
# However, the -R option *does* match a path using
# what seems like Bash rules, where the file
# separator is not assumed to match "*"
zip -R test.zip TestDir '*AAA*/*.c'
updating: TestDir/testAAAdir/File.c (stored 0%)
#-------------------------------------------------
# The -r option also seems to match by Bash rules,
# but this behaviour could be because it is a
# subset of the file path matching behaviour above
zip -r test.zip 'TestDir/*AAA*/*.c'
updating: TestDir/testAAAdir/File.c (stored 0%)