在终端、shell mac 或 shell linux 中将文件重命名为树文件夹名称

在终端、shell mac 或 shell linux 中将文件重命名为树文件夹名称

我正在使用具有以下结构的文件夹和文件树

  • \故事\00\0\00000\temp.xxx
  • \故事\00\0\00001\temp.xxx
  • ...
  • \历史\10\5\10552\temp.xxx
  • \历史\10\5\10553\temp.xxx
  • ...
  • \历史\45\9\45998\temp.xxx
  • \历史\45\9\45999\temp.xxx

我需要重命名文件,以便将 temp.xxx 更改为顺序文件名,如下所示:

  • \ 故事 \ 00 \ 0 \ 00000 \ 00000.xxx
  • \ 故事 \ 00 \ 0 \ 00001 \ 00001.xxx
  • ...
  • \ 历史记录 \ 10 \ 5 \ 10552 \ 10552.xxx
  • \ 历史记录 \ 10 \ 5 \ 10553 \ 10553.xxx
  • ...
  • \ 历史记录 \ 45 \ 9 \ 45998 \ 45998.xxx
  • \ 历史记录 \ 45 \ 9 \ 45999 \ 45999.xxx

答案1

如果您的结构是统一的,并且您的历史文件夹内的深度为 3,那么直观的方法是嵌套 for 循环,然后使用 mv 重命名。

以下代码假设您在 layer3 中的每个文件夹中都有一个文件,并且您的 /History 除目录之外不包含任何内容。

for layer1 in /History/*; do
    for layer2 in /History/$layer1/*; do
        for layer3 in /History/$layer1/$layer2/*; do
           for files in /History/$layer1/$layer2/$layer3/*; do
                mv files $layer3.xxx
            done
        done
    done
done

也许这两个链接也有帮助:

http://www.cyberciti.biz/faq/bash-for-loop/

https://stackoverflow.com/questions/539583/how-do-i-recursively-list-all-directories-at-a-location-breadth-first

答案2

您可以使用如下命令来完成此操作:

find . -name "temp*" | sed -E 's|(.*)\/(.*)\/temp(.[a-z]{3})|mv & \1\/\2\/\2\3|g' | source /dev/stdin

逐步解释。

这是您的示例输入:

$ find . -name "temp*"
./History/10/5/10552/temp.xxx
./History/10/5/10553/temp.xxx
./Stories/00/0/00000/temp.xxx
./Stories/00/0/00001/temp.xxx

我调整输出以适合所需的输出。

$ find . -name "temp*" | sed -E 's|(.*)\/(.*)\/temp(.[a-z]{3})|\1\/\2\/\2\3|g'
./History/10/5/10552/10552.xxx
./History/10/5/10553/10553.xxx
./Stories/00/0/00000/00000.xxx
./Stories/00/0/00001/00001.xxx

因此,我们将 every 转换temp*mv具有所需输出名称的命令。该命令如下所示:

$ find . -name "temp*" | sed -E 's|(.*)\/(.*)\/temp(.[a-z]{3})|mv & \1\/\2\/\2\3|g'
mv ./History/10/5/10552/temp.xxx ./History/10/5/10552/10552.xxx
mv ./History/10/5/10553/temp.xxx ./History/10/5/10553/10553.xxx
mv ./Stories/00/0/00000/temp.xxx ./Stories/00/0/00000/00000.xxx
mv ./Stories/00/0/00001/temp.xxx ./Stories/00/0/00001/00001.xxx

要执行前一个输出中的每个命令,我们必须| source /dev/stdin在命令末尾添加。

结果如下:

$ find . -name "*.xxx"
./History/10/5/10552/10552.xxx
./History/10/5/10553/10553.xxx
./Stories/00/0/00000/00000.xxx
./Stories/00/0/00001/00001.xxx

相关内容