在 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.txtfoo.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