如何按顺序递归重命名文件?

如何按顺序递归重命名文件?

我在这里要疯了。我有很多这样的文件夹

Folder 1/
Subfolder 2/
Item.01 
Item.02
Subfolder 3/
Item.01
Item.02

我想递归且按顺序重命名文件夹 1 内的所有文件,但遵循当前层次结构(如 所示)ls并将它们移动到平面结构(单个文件夹内的所有文件)。

例子:

Folder 1/
Item 01
Item 02
Item 03 (previously Item 01 on Subfolder 2)
Item 04 (previously Item 02 on Subfolder 2)
Item 05 (previously Item 01 on Subfolder 3)

这在 bash 上可能吗?非常感谢!

答案1

  1. 查看以下globstar选项如何bash帮助您:

    shopt -s globstar ; for i in ** ; do echo "$i" ; done
    

    这应该为您提供目录树中所有项目的排序列表,但它将包括文件和子目录的条目(行)。

  2. 过滤掉子目录:

    shopt -s globstar ; for i in ** ; do [ -f " $i" ] && echo "$i" ; done
    
  3. 引入一个计数器,并删除当前文件后缀:

    cnt=1
    shopt -s globstar
    for i in ** ; do
      [ -f "$i" ] && echo "${i%%.*}.$cnt"
      cnt=$((cnt=cnt+1))
    done
    
  4. 将测试语句替换echomv您选择的:

    mv "$i" "${i%%.*}.$cnt"
    
  5. (可选)globstar完成后取消设置该选项:

    `shopt +s globstar`
    

答案2

使用以下方法更容易zsh

autoload zmv # best in ~/.zshrc
cd "Folder 1"
n=0; zmv -n '**/Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

(高兴时删除-n(用于空运行))。

  • <->:任何十进制数字序列(<x-y>无边界)
  • (#qn):用于数字排序(所以Subfolder 10 Subfolder 2)。
  • ^/: 排除文件类型目录
  • ${(l:2::0:)var}:左填充(如果较大则截断), s 长度$var02。

警告注意事项:虽然 glob**/旨在匹配任何级别的子目录,包括空级别,因此匹配当前目录中的文件,但zmv它不会因为它对模式进行两次传递,一次到 glob 并第二次作为简单的模式匹配来提取捕获组(然后第二次**/Item由于缺少而进行模式匹配/)。

解决方法是使用:

zmv -n '(**/)Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

或者:

zmv -wn '**/Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

但随后zmv检测到它是递归匹配并打开深度优先顺序(以便能够安全地重命名目录)。如果您不想深度优先排序并匹配当前目录中的文件,可以使用**/( (*/)#) 的长形式:

zmv -n '(*/)#Item.<->(#qn^/)' 'Item ${(l:2::0:)$((++n))}'

例子

在:

.
├── Subfolder 1
│   ├── Item.01
│   ├── Item.02
│   └── Subsubfolder
│       └── Item.01
├── Subfolder 10
│   ├── Item.01
│   └── Item.02
└── Subfolder 2
    ├── Item.01
    └── Item.02

它给:

mv -- Subfolder\ 1/Item.01 Item\ 01
mv -- Subfolder\ 1/Item.02 Item\ 02
mv -- Subfolder\ 1/Subsubfolder/Item.01 Item\ 03
mv -- Subfolder\ 2/Item.01 Item\ 04
mv -- Subfolder\ 2/Item.02 Item\ 05
mv -- Subfolder\ 10/Item.01 Item\ 06
mv -- Subfolder\ 10/Item.02 Item\ 07

相关内容