【问题标题】:rename recursively adding parenthere if folder name ending with 4 digits in bash如果文件夹名称在 bash 中以 4 位数字结尾,则递归重命名添加括号
【发布时间】:2020-03-13 20:25:27
【问题描述】:

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

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

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]+$)/(\1)/g")

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

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


done

是否有人可以查看或/和建议一些指导以允许 mv 找到初始文件夹及其目标?

【问题讨论】:

  • 要递归重命名的文件夹吗?像这样的结构:str 123/str2 456/ 必须重命名为str (123)/str2 (456)?你需要那个find 选项,让它从最深的目录遍历目录,它在人的某个地方......
  • 是的,确实是这个想法。

标签: bash rename recursive-query parentheses mv


【解决方案1】:

以下命令:

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 之后的第一个参数,该参数用于$0,请参阅man bash /-c
  • 最后-prune 以防止匹配时在子树中搜索,(假设2004/2004 然后mv 2004/2004 "2004/(2004)" 或 mv 2004/2004 (2004)/2004' 将失败)

【讨论】:

  • bash -c 'for dir'... 对我来说看起来很奇怪。与-exec bash -c 'mv "$1" "${1%[0-9][0-9][0-9][0-9]}(${1#${1%[0-9][0-9][0-9][0-9]}})"' -- {} \; 这样的单个进程相比,它是否节省了内存/执行速度?
  • 避免每个mv启动一个batch过程,做benchmark看看
  • 但与您的评论不同,它不会重命名嵌套目录
【解决方案2】:

在查找和重命名文件以进行所有转义时,我发现 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})/, '\1\2(\3)')
    FileUtils.mv dir,new_name
end

【讨论】:

    【解决方案3】:

    $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]+$)/(\1)/g" <<< "${orgdir}")"
    done < <(find . -depth -name '*[0-9]' -type d)
    

    【讨论】:

      猜你喜欢
      • 2020-08-29
      • 2012-03-25
      • 2022-01-10
      • 2013-04-14
      • 1970-01-01
      • 2014-05-22
      • 1970-01-01
      • 2010-12-11
      • 2021-12-19
      相关资源
      最近更新 更多