我正在编写一个 bash 脚本,该脚本调用一个外部程序,该程序生成一个格式为 ########.zip 的 zip 文件,其中 '#'s# 可以是任何十进制数字。没有办法预测数字将是什么。
到目前为止,我已经能够通过使用正则表达式 [0-9][0-9]*zip 来完成诸如移动 zip 文件和解压缩之类的事情。但是,现在我需要在目录名称######## 下的存档中添加一个 txt 文件,其中数字与存档名称相同。所以,如果存档是 12345678.zip,我需要添加文件 12345678/foo.txt。
我能看到的唯一方法是创建目录'12345678'并将文件复制到那里,然后将目录添加到存档中。但是我不知道如何获取存档的名称,以便我可以创建目录。
我能想到的最好的办法是使用反引号将 ls -l 的输出分配给一个变量,然后解析它以获得文件名部分。但是必须有更简单的方法吗?
如果重要的话,我使用 7z 作为 zip 实用程序。
谢谢!
回答1
您要的不是正则表达式,而是“全局表达式”。特别是,如果您想匹配任意数量的数字,可以使用称为扩展通配符或“extglobs”的 bash 功能来完成。在 https://wiki.bash-hackers.org/syntax/pattern#extended_pattern_language 了解更多信息。
#!/usr/bin/env bash
# ^^^^- NOT sh
shopt -s extglob
for f in +([[:digit:]]).zip; do
digits=${f%.zip}
mkdir -p "$digits"
echo hello >"$digits/foo.txt"
zip "$f" "$digits/foo.txt"
done
在https://wiki.bash-hackers.org/syntax/pe digits=${f%.zip}
中,我们将文件名末尾的.zip
和store放在变量digits
中。
将上述内容扩展为在临时目录中工作并自行清理:
#!/usr/bin/env bash
# ^^^^- NOT sh
shopt -s extglob
olddir=$PWD
for f in +([[:digit:]]).zip; do
digits=${f%.zip}
tempdir="$(mktemp -d -t zipupdate.XXXXXX)"
(
cd "$tempdir" || exit
mkdir -p "$digits" || exit
echo hello >"$digits/foo.txt" || exit
zip "$olddir/$f" "$digits/foo.txt"
)
rm -rf "$tempdir"
done
回答2
由于 OP 正在使用 7z
我们可以使用 rn
选项来重命名存档中的文件并消除创建/删除临时子目录的需要......
设置:
$ 'rm' -rf zipdir
$ mkdir zipdir
$ cd zipdir
$ zipfile='12345678.zip'
$ digits="${zipfile//.zip/}"
$ declare -p digits
declare -- digits="12345678"
$ echo abc > sample.txt
$ echo def > foo.txt
用 sample.txt
和 foo.txt
创建/填充 ${zipfile}
:
$ 7z a "${zipfile}" sample.txt foo.txt
... snip ...
Archive size: 158 bytes (1 KiB)
Everything is Ok
$ 7z l "${zipfile}"
... snip ...
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 ..... 4 4 foo.txt
2022-05-14 15:53:16 ..... 4 4 sample.txt
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 8 8 2 files
现在添加 ${digits}
目录作为 foo.txt
的前缀:
$ 7z -- rn "${zipfile}" foo.txt "${digits}/foo.txt"
... snip ...
Archive size: 306 bytes (1 KiB)
Everything is Ok
$ 7z l "${zipfile}"
... snip ...
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 ..... 4 4 12345678/foo.txt
2022-05-14 15:53:16 ..... 4 4 sample.txt
------------------- ----- ------------ ------------ ------------------------
2022-05-14 15:53:16 8 8 2 files