【问题标题】:Recursively rename folders递归重命名文件夹
【发布时间】:2017-03-06 23:04:18
【问题描述】:

我有一个 Windows 备份程序,它正在创建大量子目录,最后带有“$”。同一备份程序的 Linux 客户端在目录名称的末尾需要一个“:”,以便恢复文件夹。一些文件夹有“$”而其他文件夹没有 - 与内部版本控制系统有关。

如果我将文件从 windows 客户端恢复到另一个 windows 盒子,备份程序工作得很好。程序在 Windows 中使用“$”,因为“:”在路径中无效。

我正在寻找 bash 中的递归重命名,它将逐步遍历路径并找到最后带有单个“$”字符的所有文件夹,并将其替换为“:

我的测试数据是这样的:

./a$
./b$
./c$
./white space$
./white space$/another test$
./white space$/another test$/a$
./white space$/another test$/b$
./white space$/another test$/x
./white space$/another test$/y
./white space$/test
./white space$/test 2
./white space$/testing$

我试过了:

find . -type d -name "*$" 

这给了我需要重命名的文件夹列表

./a$
./b$
./c$
./white space$
./white space$/another test$
./white space$/another test$/a$
./white space$/another test$/b$
./white space$/testing$


find . -type d -name "*$" | sed 's/$$/\:/'   

给出了我正在寻找的最终结果

./a:
./b:
./c:
./white space:
./white space$/another test:
./white space$/another test$/a:
./white space$/another test$/b:
./white space$/testing:

但我无法在同一步骤中重命名它。另外,我需要它以相反的顺序工作(从最深的匹配开始并返回),这样第一次重命名不会使其余的失败。

【问题讨论】:

    标签: recursion sed rename


    【解决方案1】:

    您可以使用this solution 处理所有空格和特殊字符,然后使用printf '%d' 您可以获得每个匹配目录的深度,然后执行降序sort 并通过@ 构建rename 命令987654326@ 与sh 一起执行:

    while IFS= read -r -d '' n; do
      printf '%q\n' "$n"
    done < <(find . -type d -name "*$" -printf '%d|' -print0) | \
    sort -r -k1 | \
    awk -F '|' '{ printf "rename -v -n '\''s/\\$$/:/'\'' %s \n",$2 }' | \
    sh
    

    rename -n 只会打印要重命名的文件名,如果您准备好了,请执行重命名操作删除 -n

    while IFS= read -r -d '' n; do
      printf '%q\n' "$n"
    done < <(find . -type d -name "*$" -printf '%d|' -print0) | \
    sort -r -k1 | \
    awk -F '|' '{ printf "rename -v '\''s/\\$$/:/'\'' %s \n",$2 }' | \
    sh
    

    显示进度

    data=$(while IFS= read -r -d '' n; do
      printf '%q\n' "$n"
    done < <(find . -type d -name "*$" -printf '%d|' -print0) | \
    sort -r -k1);
    
    count=$(echo "$data" | awk 'END{ print NR}');
    
    echo "$data" | awk -F '|' -v count=$count '{ printf "echo -n \""NR"/"count" file : \";rename -v -n  '\''s/\\$$/:/'\'' %s \n",$2 }' | \
    sh
    

    输出:

    1/8 file : ./white space$/another test$/b$ renamed as ./white space$/another test$/b:
    2/8 file : ./white space$/another test$/a$ renamed as ./white space$/another test$/a:
    3/8 file : ./white space$/testing$ renamed as ./white space$/testing:
    4/8 file : ./white space$/another test$ renamed as ./white space$/another test:
    5/8 file : ./white space$ renamed as ./white space:
    6/8 file : ./c$ renamed as ./c:
    7/8 file : ./b$ renamed as ./b:
    8/8 file : ./a$ renamed as ./a:
    

    另类

    更直接的解决方案,使用rnm批量重命名工具:

    rnm -rs '/\$$/:/g' -dp -1 *
    

    【讨论】:

    • 很高兴为您提供帮助,如果您的问题解决了,您可以接受答案
    • 我今天早上在我的生产数据上运行它,它在第一遍运行并重命名了大约 90% 的文件夹,但它必须在某个地方将树中的基本文件夹重命名为大约 300找不到文件夹。第二次运行脚本解决了这个问题。想知道是否有办法在重命名时输出进度?
    • 您是否第一次使用-n 运行以查看受影响的目录列表,您错过的文件夹是否已登记?我在帖子中添加了进度功能
    猜你喜欢
    • 2014-08-11
    • 2017-08-18
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 2020-11-23
    • 1970-01-01
    • 2011-12-25
    • 1970-01-01
    相关资源
    最近更新 更多