我有一个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:
但是我不能让它在同一步骤中重命名。此外,我需要它以相反的顺序工作(从最深的匹配开始并返回工作),以便第一次重命名不会使其余的失败。
答案 0 :(得分:0)
您可以使用this solution来处理所有空格和特殊字符,然后使用printf '%d'
可以获取每个匹配目录的深度,然后执行降序sort
并构建一个通过rename
执行的awk
命令将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 *