1

嗨,有一堆文件夹,里面有一个 zip 文件,路径如下所示

/folder/subfolder/archive.zip
/folder/subfolder1/archive1.zip
/folder/subfolder2/archive2.zip
/folder/subfolder3/zip3.zip
/folder/subfolder4/zip4.zip
etc...

我需要输出是这样的

/folder/subfolder/preview.zip
/folder/subfolder1/preview.zip
/folder/subfolder2/preview.zip
/folder/subfolder3/preview.zip
/folder/subfolder4/preview.zip
etc...

每个文件夹也只有一个 zip,因此我不必进行覆盖工作,而且我只需要将每个文件夹中的每个 zip 重命名为 preview.zip,无论每个子目录中的名称如何,我如何在 bash 中做到这一点?

感谢您的任何帮助

4

4 回答 4

4

像这样的东西应该可以完成这项工作:

for j in **/*.zip; do mv "$j" "${j%/*.zip}/preview.zip"; done

正如 SiegeX 所指出的,请注意,要使用递归通配符,您必须设置该globstar选项,并且该选项仅在 bash 4.x 中可用

于 2012-01-18T08:38:44.620 回答
3

您可以使用 Bash 的参数替换来做到这一点:

bash-3.2$ for archive in folder/subfolder*/*.zip; do
    echo "Archive = ${archive}, Preview = ${archive%/*}/preview.zip"
done
Archive = folder/subfolder/archive.zip, Preview = folder/subfolder/preview.zip
Archive = folder/subfolder1/archive1.zip, Preview = folder/subfolder1/preview.zip
Archive = folder/subfolder2/archive2.zip, Preview = folder/subfolder2/preview.zip
Archive = folder/subfolder3/zip3.zip, Preview = folder/subfolder3/preview.zip
Archive = folder/subfolder4/zip4.zip, Preview = folder/subfolder4/preview.zip

哪里会从最后一个中${archive%/*}剥离一切。/${archive}

这将允许您验证将运行的命令。将其更改为:

mv "${archive}" "${archive%/*}/preview.zip" 

...重命名文件(即使它们的名称中有空格)。

于 2012-01-18T08:41:36.090 回答
0
#!/bin/bash
while read file; do
  echo mv "$file" "${file%/*}/preview.zip"
done < <(find /folder -type f -name "archive*.zip")

注意:如果输出看起来足够,请删除echo并重新运行脚本以进行实际更改

于 2012-01-18T08:34:44.037 回答
0

这可能对您有用,但尚未经过全面测试:

find /folder -maxdepth 1 -mindepth 1 -type d -exec mv {}/archive*.zip {}/preview.zip \;

在您的示例下非常严格地工作,这应该 find在 下的所有目录/folder,最大和最小深度为 1(即只有在 中的目录/folder,因为这似乎是您想要的)并mv为每个目录下的文件执行命令。

于 2012-01-18T08:40:21.493 回答