在 Bash 中使用正则表达式读取文件名
Reading filename using regexp in Bash
我正在编写一个 bash 脚本,该脚本调用一个外部程序,该程序生成一个格式为 ########.zip 的 zip 文件,其中“#”# 可以是任何十进制数字.没有办法预测数字会是什么。
到目前为止,我已经能够通过使用正则表达式 [0-9][0-9]*zip 来移动和解压缩 zip 文件。但是,现在我需要将一个 txt 文件添加到目录名称 ######## 下的存档中,其中数字与存档名称相同。所以,如果存档是 12345678.zip,我需要添加文件 12345678/foo.txt.
我能看到的唯一方法是创建目录“12345678”并将文件复制到那里,然后将该目录添加到存档中。但是我不知道如何获取存档的名称以便我可以创建目录。
我能想到的最好办法是使用反引号将 ls -l 的输出分配给一个变量,然后对其进行解析以仅获取文件名部分。但是必须有更简单的方法吗?
如果重要的话,我正在使用 7z 作为 zip 实用程序。
谢谢!
您要的不是正则表达式,而是“glob 表达式”。特别是,如果您想匹配任意数量的数字,可以使用称为扩展通配符或“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
在parameter expansiondigits=${f%.zip}
中,我们把文件名末尾的.zip
去掉,剩下的存入变量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
由于 OP 使用 7z
我们可以使用 rn
选项重命名存档中的文件 和 无需 create/delete 临时子目录 ...
设置:
$ '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
Create/populate ${zipfile}
与 sample.txt
和 foo.txt
:
$ 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
我正在编写一个 bash 脚本,该脚本调用一个外部程序,该程序生成一个格式为 ########.zip 的 zip 文件,其中“#”# 可以是任何十进制数字.没有办法预测数字会是什么。
到目前为止,我已经能够通过使用正则表达式 [0-9][0-9]*zip 来移动和解压缩 zip 文件。但是,现在我需要将一个 txt 文件添加到目录名称 ######## 下的存档中,其中数字与存档名称相同。所以,如果存档是 12345678.zip,我需要添加文件 12345678/foo.txt.
我能看到的唯一方法是创建目录“12345678”并将文件复制到那里,然后将该目录添加到存档中。但是我不知道如何获取存档的名称以便我可以创建目录。
我能想到的最好办法是使用反引号将 ls -l 的输出分配给一个变量,然后对其进行解析以仅获取文件名部分。但是必须有更简单的方法吗?
如果重要的话,我正在使用 7z 作为 zip 实用程序。
谢谢!
您要的不是正则表达式,而是“glob 表达式”。特别是,如果您想匹配任意数量的数字,可以使用称为扩展通配符或“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
在parameter expansiondigits=${f%.zip}
中,我们把文件名末尾的.zip
去掉,剩下的存入变量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
由于 OP 使用 7z
我们可以使用 rn
选项重命名存档中的文件 和 无需 create/delete 临时子目录 ...
设置:
$ '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
Create/populate ${zipfile}
与 sample.txt
和 foo.txt
:
$ 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