使用 find 和 sed 重命名多个子文件夹

使用 find 和 sed 重命名多个子文件夹

我想要做的是重命名当前树中任意位置的文件夹,而不一定直接重命名工作目录中的文件夹。我需要做的是:

  • “A 1”变成“A 01”
  • “A 2”变成“A 02”
  • “A 09”被忽略

我最终得到了这个:

find . -type d -regex '.*A [0-9]$' -execdir mv "{}" "$(echo '{}' | sed 's_[0-9]_0&_')" \;

为了测试这一点,我稍微降低了复杂性:

find . -type d -regex '.*A [0-9]$' -execdir echo "$(echo '{}' | sed 's_[0-9]_0&_')" \;

find列出了我想要的所有文件夹,但中的模式sed似乎在文件夹名称中找不到匹配项。如果它单独执行,它会起作用,所以我猜想需要转义的字符存在问题。

答案1

更新:添加了一个可以处理任何/所有有效文件名字符的版本,除了\x01用作 sed 分隔符的 之外......我已经A.*更新示例,因为我正在测试A"'。当然,只需更改为您需要的任何内容即可。

findx="\(.*/\)\(A.* \)\([0-9]\)$"
replx="&\x00\1\20\3\x00"; I=$'\x01'
find . -depth -type d -regex "$findx" | 
  sed -n "s$I$findx$I$replx$I p" |
    tr -d '\n' | 
      xargs --verbose -0n2 mv 

perl下面是一个使用而不是 的示例sed
请注意perl 的正则表达式PCRE并不完全相同posix 扩展 EREfind本例中所使用的。但它们确实具有足够的共同点,因此在本例中可以使用相同的正则表达式模式。

export findx='(.*/)(A.* )([0-9])$'
find . -depth -type d -regextype posix-extended -regex "$findx" |
  perl -l000pe 's/$ENV{'findx'}/$_\000$1${2}0$3/' |
    xargs --verbose -0n2 mv 

下一个版本无法处理文件名中的单引号'

使用标准正则表达式模式

regex='\(.*/\)\(A \)\([0-9]\)$'
find . -depth -type d -regex "$regex" |
  sed -n "s|$regex|'&' '\1\20\3'|p" |
    xargs --verbose -n2 mv 

使用扩展正则表达式模式

regex='(.*/)(A )([0-9])$'
find . -depth -regextype posix-extended -type d -regex "$regex" |
  sed -nr "s|$regex|'&' '\1\20\3'|p" |
    xargs --verbose -n2 mv 

需要该-depth选项,以便更深入地在重命名任何父目录之前,先重命名嵌套目录。

请注意,该脚本不会测试是否已经存在与新名称同名的目录。

相关内容