bash - 在 Bash 中使用正则表达式读取文件名

我正在编写一个 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.txtfoo.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

相似文章

r - R str_split_i inside ifelse 有两个条件

我需要使用较短的映射文件替换较长文件中的学生姓名。较长的文件仅包含名字和考试文件名。映射文件具有全名和考试文件名。我需要从映射文件中获取全名。必须满足两个条件,学生的名字必须在两个文件中匹配,并且由于...

随机推荐

最新文章