使用的答案-execdir更简单,但只能使用GNU find等find支持的版本-execdir,因为POSIX只能指定-exec.
如果你只是想使用bash,那么要想做到这一点是非常棘手的,因为你正在重命名find正在搜索的目录.即使您通过使用-depth选项获得正确的顺序find,您也需要确保只使用每个组件重写路径的最后一个组件-exec.以下是Bash常见问题解答中给出的一个示例的一个微不足道的变体,似乎对我有用:
find . -depth -name "*_*" -exec bash -c 'dir=${1%/*} base=${1##*/}; mv "$1" "$dir/${base//_/ }"' _ {} \;
Run Code Online (Sandbox Code Playgroud)
该FAQ答案有更多关于递归命名文件夹的问题的讨论,这可能是有意义的.
更新:由于这种单线程相当复杂,为了解释起见,可能值得将其分解一点.本质上,find命令是:
find . -depth -name "*_*" -exec bash -c [SOME-STUFF] _ {} \;
Run Code Online (Sandbox Code Playgroud)
换句话说,找到包含下划线的所有目录,并且对于每个这样的目录,从最深处开始,运行bash脚本[SOME-STUFF],参数0为_(表示我们不关心它)和参数1作为找到的文件的名称.(find将文件名替换为{}after -exec.\;只是终止-exec运行的命令.)
然后该[SOME-STUFF]部分由以下部分组成:
dir=${1%/*}
Run Code Online (Sandbox Code Playgroud)
...使用参数扩展,将从(文件名)/*的末尾删除最短匹配$1并设置dir为结果.同样,这部分:
base=${1##*/}
Run Code Online (Sandbox Code Playgroud)
... */从开头删除最长匹配$1并设置base为结果.所以base这只是路径的最后一个组成部分.
然后重命名实际上是由mv命令完成的,即:
mv "$1" "$dir/${base//_/ }"
Run Code Online (Sandbox Code Playgroud)
这再次使用参数扩展,这次使用${parameter/pattern/string}语法.文件名($1)被重命名$dir后跟,$base但每个下划线都$base替换为空格.
是的,只需 cd 到 /dir 并:
find -depth -type d -execdir rename 's/_/ /g' {} \;
Run Code Online (Sandbox Code Playgroud)
根据发行版的不同,您需要 perl 重命名(有时是预命名)。
如果
file $(type -p rename)
Run Code Online (Sandbox Code Playgroud)
输出包含 ELF,看起来很糟糕;)
添加了编辑 -深度和-execdir
| 归档时间: |
|
| 查看次数: |
5391 次 |
| 最近记录: |