Dav*_*hen 10
虽然这里已经有很好的答案,但我发现这更直观,在bash:
find aaa -type f -exec sh -c 'new=$(echo "{}" | tr "/" "-" | tr " " "_"); mv "{}" "$new"' \;
Run Code Online (Sandbox Code Playgroud)
aaa您现有的目录在哪里。它包含的文件将被移动到当前目录(只留下 aaa 中的空目录)。tr处理目录和空格的两个调用(没有转义斜杠的逻辑 - 读者练习)。
我认为这更直观且相对容易调整。即find如果说我只想找到 .png 文件,我可以更改参数。我可以更改tr呼叫,或根据需要添加更多呼叫。如果我想直观地检查它是否会做正确的事情,我可以添加echo之前mv(然后echo仅在事情看起来正确时重复而不额外添加:
find aaa -name \*.png -exec sh -c 'new=$(echo "{}" | tr "/" "-" | tr " " "_"); echo mv "{}" "$new"' \;
Run Code Online (Sandbox Code Playgroud)
另请注意,我使用的是find aaa... 而不是find .... 或find aaa/... 因为后两者会在最终文件名中留下有趣的工件。
警告:我直接在浏览器中输入了大部分命令。警告讲师。
使用 zsh 和zmv:
zmv -o -i -Qn '(**/)(*)(D)' '${1//\//-}$2'
Run Code Online (Sandbox Code Playgroud)
说明:该模式**/*递归地匹配当前目录子目录中的所有文件(它不匹配当前目录中的文件,但这些不需要重命名)。前两对括号是可以在替换文本中称为$1和 的组$2。最后一对括号添加了D glob 限定符,以便不会省略点文件。-o -i表示将-i选项传递给,mv以便在现有文件将被覆盖时提示您。
仅使用 POSIX 工具:
find . -depth -exec sh -c '
for source; do
case $source in ./*/*)
target="$(printf %sz "${source#./}" | tr / -)";
mv -i -- "$source" "${target%z}";;
esac
done
' _ {} +
Run Code Online (Sandbox Code Playgroud)
说明:case语句省略了当前目录和当前目录的顶级子目录。target包含源文件名 ( $0),./去掉前导,所有斜线都替换为破折号,加上最后的z. 最后z是在文件名以换行符结尾的情况下:否则命令替换将删除它。
如果你find不支持-exec … +(OpenBSD,我在看着你):
find . -depth -exec sh -c '
case $0 in ./*/*)
target="$(printf %sz "${0#./}" | tr / -)";
mv -i -- "$0" "${target%z}";;
esac
' {} \;
Run Code Online (Sandbox Code Playgroud)
使用 bash(或 ksh93),您不需要调用外部命令来用破折号替换斜杠,您可以使用带有字符串替换构造的 ksh93 参数扩展${VAR//STRING/REPLACEMENT}:
find . -depth -exec bash -c '
for source; do
case $source in ./*/*)
source=${source#./}
target="${source//\//-}";
mv -i -- "$source" "$target";;
esac
done
' _ {} +
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4019 次 |
| 最近记录: |