【问题标题】:Renaming folders, files and subfolders in bash在 bash 中重命名文件夹、文件和子文件夹
【发布时间】:2011-12-30 06:01:19
【问题描述】:

我的 bash 脚本有问题... 我想以递归方式重命名所有文件、文件夹和子文件夹,从 小写到大写(反之亦然)。 我已经写了这个脚本,但是它不起作用。

find . -depth -iname \* -exec mv {} `echo {} | tr [:upper:] [:lower:]` \;

有什么建议吗? 谢谢

【问题讨论】:

    标签: file bash directory renaming


    【解决方案1】:

    为什么不使用简单的while循环:

    find testdir/ -depth | while read file; do NEWNAME=$(dirname "$file")/$(echo $(basename "$file") | tr '[:lower:]' '[:upper:]'); mv "$file" "$NEWNAME"; done
    

    【讨论】:

    • 我尝试使用您的第一个脚本,但它只更改了文件夹树的第一个“级别”。例如,如果我有 DocumentsFolder-JobFolder-Test.txt,则在执行后我有 DOCUMENTFOLDER-JobFolder-Test.txt。我想要所有文件夹、子文件夹和文件的大写,例如 DOCUMENTFOLDER-JOBFOLDER-TEST.TXT。
    【解决方案2】:

    问题是你的反引号命令echo {} | tr [:upper:] [:lower:]首先被shell扩展,所以find实际上看到的参数是

    find . -depth -iname \* -exec mv {} {} \;
    

    (在输入 {} 上运行 tr [:upper:] [:lower:] 只会再次返回 {})。

    这是一种解决方法,使用子shell 作为-exec 命令:

    find . -mindepth 1 -depth -iname \* -exec \
        sh -c 'mv "$0" "`tr \[:upper:\] \[:lower:\] <<<"$0"`"' {}  \;
    

    或者更易读,使用 $() 语法:

    find . -mindepth 1 -depth -iname \* -exec \
        sh -c 'mv "$0" "$(tr "[:upper:]" "[:lower:]" <<<$0)"' {}  \;
    

    请注意,您还需要引用 tr 字符范围以阻止 shell 扩展它们!

    添加-mindepth 1 也是一个好主意,这样您在尝试运行mv . . 时就不会出错。

    【讨论】:

    • 感谢您的解释...我尝试运行脚本,但出现很多语法错误,文件夹子文件夹和文件名没有变化
    • 看起来你已经通过其他方式得到了答案,但为了记录,原始代码在带有空格的文件名上无法正常工作,这可能是问题所在。我现在已经纠正了。一旦你达到这么多引用级别,循环解决方案开始看起来相当不错,确实;-)
    • 感谢您的回答!但是
    • &lt;&lt;&lt; 在 bash 中创建一个“here string”,这意味着后面的任何单词都成为命令的标准输入,就像some-command &lt;some-file 使some-file 的内容成为标准输入一样)。例如,尝试tr a-z A-Z &lt;&lt;&lt;"a test string"。在这种情况下,&lt;&lt;&lt;$0 将第一个参数$0 传递给sh -c ...——find 通过替换{} 传入的文件名——并将其作为tr ... 的输入。 (顺便说一句,通常脚本的第一个参数是 $1,但 sh -c 的行为不同——请参阅 Bash 手册)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-02-25
    • 2016-07-24
    • 1970-01-01
    • 2017-07-25
    • 2016-01-25
    • 2012-03-25
    • 1970-01-01
    相关资源
    最近更新 更多