递归更改文件夹的名称 - Bash

递归更改文件夹的名称 - Bash

我想将所有文件重命名Caudate_masks为小写:caudate_masks

在我的目录中,我有几个文件夹,其中一个名为Controls,另一个名为Patients。在每个文件夹内,您都可以找到Caudate_masks文件夹。

   Controls

   └───C01
   │   └─── Caudate_masks
   │   └─── ...     
   └───C02
   │   └─── Caudate_masks
   │   └─── ...
   └───C03
   │   └─── Caudate_masks
   │   └─── ...


   Patients

   └───H01
   │   └─── Caudate_masks
   │   └─── ...

这就是我所拥有的:

#!/bin/bash
DIR="/media/roy/Analysis"
for group in Controls Patients; do
    cd $DIR/$group || exit
    for folder in *; do
        for cortical in "$folder/"*; do
            if [ $cortical = "$folder/Caudate_masks" ]; then
                mv $cortical caudate_masks
            fi
        done;
    done;
done;

如果我执行:

if [ $cortical = "$folder/Caudate_masks" ]; then
                echo $cortical

我得到了所有感兴趣的文件夹的列表,但是,mv $cortical caudate_masks并没有改变名称,而是移动了文件,并且rename没有出现有效的功能。

答案1

安装rename软件包:

sudo apt install rename

然后它是一个 shell 单行:

[sh @ balrog] ~/tmp 27 % tree
.
├── a
│   └── Caudate_masks
├── b
│   └── Caudate_masks
└── c
    └── Caudate_masks

6 directories, 0 files

[sh @ balrog] ~/tmp 28 % rename 's/Caudate_masks/caudate_masks/' **/Caudate_masks

[sh @ balrog] ~/tmp 29 % tree
.
├── a
│   └── caudate_masks
├── b
│   └── caudate_masks
└── c
    └── caudate_masks

6 directories, 0 files

请注意,现代 shell(bash、zsh)支持**通配符,意思是“此目录树中的某处”。


脚本无法按预期运行的原因是在此代码片段中

        for cortical in "$folder/"*; do
            if [ $cortical = "$folder/Caudate_masks" ]; then
                mv $cortical caudate_masks
            fi
        done;

您的旧名称包含目录(来自$folder),但新名称不包含。如果您将该行更改为

                mv $cortical $folder/caudate_masks

答案2

如果您不想/无法安装rename,那么您可以使用 bash shell 的,,参数扩展在命令中执行大小写转换,find例如。

find Controls/ Patients/ -type d -name 'Caudate_masks' -execdir bash -c '
  for f; do mv "$f" "${f,,}"; done
' bash {} +

相关内容