【问题标题】:Mass-renaming of files with double quote in name名称中带有双引号的文件的大规模重命名
【发布时间】:2017-05-23 15:39:35
【问题描述】:

我有一个文件系统,其中包含很多我想在 Windows 机器上使用的文件。文件名中的非法字符是个问题,所以我搜索了一个 bash 命令,它递归地清理所有文件中的非法字符。

我找到了这个解决方案 (https://stackoverflow.com/a/19009177/7394134):

find . -name "*[<>:\\|?*]*" -exec bash -c 'x="{}"; y=$(sed "s/[<>:\\|?*]\+/-/g" <<< "$x") && mv "$x" "$y" ' \;

它适用于大多数文件,但它不适用于包含双引号的文件并且失败并显示以下错误消息:

bash:(双引号后的文件名的其余部分):找不到命令

我发现了一些稍微不同的问题,例如“删除包含双引号的文件”或“使用 sed 在文件中删除双引号”,但不幸的是,我无法将他们的解决方案转移到成功修改上述命令。

备注:即使可能有更简单的单行代码(我很想看到它们!),我想了解在通过 -exec 将文件名传递给执行的三个命令时的转义重击。是否可以创建一个以这种方式同时删除双引号和单引号的命令?

【问题讨论】:

    标签: linux bash sed find


    【解决方案1】:

    一种方法是正确地对bash 中涉及command-substitution 的所有操作进行双引号,即$(..)。不这样做会让 shell 将执行的命令的结果(如果结果有空格/特殊字符)视为单独的单词。如果在结果上运行任何命令,则由于参数不正确(在您可能的情况下,可能是由于对变量 y 的分配不正确)而容易出错

    下面有一个简单的技巧,双引号你的sed 命令,比如,

    find . -name "*[<>:\\|?*]*" -exec bash -c 'x="{}"; y="$(sed "s/[<>:\\|?*]\+/-/g" <<< "$x")" && mv "$x" "$y" ' \;
    

    可以为您解决问题。

    或者,如果您对一种更简单的方法来处理名称中包含特殊字符的文件感兴趣,

    使用GNU find 中的-print0 选项来处理文件名中带有特殊字符/空格的文件,使用bash process-substitution。一个合适的脚本是

    #!/bin/bash
    
    while IFS=  read -r -d $'\0' file
    do
        newfile="$(sed "s/[<>:\\|?*]\+/-/g" <<< "$file")" 
        mv -v -- "$file" "$newfile"    
    done <(find . -name "*[<>:\\|?*]*" -print0)
    

    -print0 (a GNU find specific option)find 命令返回的每个文件/目录的末尾附加一个NULL 字符,以便处理带有空格/特殊字符和read (-d$'\0') 的名称,拆分输出来自find,以 \0 作为分隔符。

    【讨论】:

      猜你喜欢
      • 2013-12-05
      • 2021-11-15
      • 2013-07-13
      • 2014-01-29
      • 2012-08-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多