如果 bash 中的文件夹名称以 4 位数字结尾,则递归重命名并在此处添加括号

rename recursively adding parenthere if folder name ending with 4 digits in bash

我一直在尝试递归重命名名称以四位数字结尾的文件夹。

例如,我有一个这样的文件夹名称:

this is the name 2004

我正在尝试将其重命名为:

this is the name (2004)

我尝试拆分名称的前缀和数字部分,但是我无法 mv 重命名这些文件夹。

这是我目前试过的代码:

#!/bin/bash
F=$(find . -name '*[0-9]' -type d)

for i in "$F";
do

R2=$(echo "$i" | awk '{print $NF}')
R1=$(echo "$i" | sed 's/.\{4\}$//')
R3=$(echo "$R2" | sed -r "s/(^[0-9]+$)/()/g")

mv "$i" "$R1 $R3"
# Even tried:

mv "\"$i"\" "\"$R2 $R3"\"


done

是否有人可以查看 or/and 提出一些指导以允许 mv 找到初始文件夹及其目的地?

以下命令:

find -name '*[0-9][0-9][0-9][0-9]' -type d -exec bash -c 'for dir; do mv "$dir" "${dir%[0-9][0-9][0-9][0-9]}(${dir#${dir%[0-9][0-9][0-9][0-9]}})"; done' - {} + -prune

应该可以。

  • 双引号包围变量扩展
  • ${dir%[0-9][0-9][0-9][0-9]} 删除最后 4 位数字后缀
  • ${dir#${dir%[0-9][0-9][0-9][0-9]}} 删除前面的前缀
  • -exec bash -c '..' - {} + - 跳过 -c command 之后的第一个参数,这是 [=16=] 所采用的,参见 man bash /-c
  • -prune 在末尾以防止匹配时在子树中搜索,(假设 2004/2004 然后 mv 2004/2004 "2004/(2004)" 或 mv 2004/2004 (2004)/2004' 会失败)

我发现 Bash 在查找和重命名文件以满足所有转义文件的需要时很烦人。这是一个更干净的 Ruby 解决方案:

#!/usr/bin/ruby

require 'fileutils'

dirs = Dir.glob('./**/*').select {|x| x =~ / [0-9]*/ }

dirs.sort().reverse().each do |dir| 
    new_name=dir.gsub(/(.*)( )([0-9]{4})/, '()')
    FileUtils.mv dir,new_name
end

$F有多个目录时,for循环会将其视为一个带有换行符的长条目(尝试echo "F=[$F]")。
同样使用 -depth,你可能有 topdir 2004/subdir 2004。所以首先重命名子目录。

当目录没有换行时,你可以试试

#!/bin/bash

while IFS= read -r orgdir; do
   mv "${orgdir}" "$(sed -r "s/([0-9]+$)/()/g" <<< "${orgdir}")"
done < <(find . -depth -name '*[0-9]' -type d)