我有一个包含 15000 个 zip 文件的目录。我想重命名所有在解压后包含以下格式的文件的文件
YYYYMMDD_IPC.csv
其中YYYYMMDD
恰好是日期,但就本题而言, 是任意 8 位数字的字符串。然后,zip 文件本身应重命名为
YYYYMMDD_IPC.zip.
我已经得到了以下命令行,但我不知道如何YYYYMMDD
从包含的文件中捕获以用于重命名 zip 文件:
find . -iname '*.zip' | while read file; do unzip -l "$file" | grep -q -P '\d{8}_IPC.csv' && echo $file; done 2>&-
感谢您的阅读。
答案1
find . -iname '*.zip' -exec bash -c 'name=$(unzip -qql "$1" '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1); [ "$name" ] && mv "$1" "${name%csv}zip"' none {} ';'
怎么运行的
该命令的格式为:
find . -iname '*.zip' -exec bash -c '...' none {} ';'
这将在当前目录及其下的所有子目录中搜索 .zip 文件。对于找到的每个这样的文件,都会执行单引号中的 bash 命令。找到的文件的名称作为参数一提供给$1
bash 命令。在我们的例子中,bash 命令有两个部分。第一部分提取 csv 文件名并将其保存在 bash 变量中name
:
name=$(unzip -qql "$1" '*_IPC.csv' | grep -oE '[[:digit:]]{8}_IPC.csv' | head -n1)
上述用途命令替换:运行其中的命令$(...)
并捕获其标准输出。在本例中,我们将其分配给变量name
。该命令unzip -qql "$1" '*_IPC.csv'
会悄悄地从 zip 文件中提取与 glob 匹配的所有文件名*_IPC.csv
。我们不需要限制到 glob,*_IPC.csv
但如果 zip 文件中有许多文件,这可能会加快速度。
grep 命令rep -oE '[[:digit:]]{8}_IPC.csv'
进一步仅选择以 8 位数字开头的名称。该head -n1
命令选择找到的第一个这样的名称。如果只有一个这样的名称,head -n1
则不需要。但是,保留head
可以加快速度,因为它会导致管道在第一个匹配后终止。
第二部分测试我们是否成功获取非空name
,如果是,则重命名 zip 文件:
[ "$name" ] && mv "$1" "${name%csv}zip"
上述用途删除后缀将 csv 文件名更改为 zip 文件名。 删除后缀后${name%csv}
返回。 添加 zip 后缀。$name
csv
${name%csv}zip