2017-01-09 83 views
1

我有一个文件系统,其中包含大量我想在Windows计算机上使用的文件。文件名中的非法字符是一个问题,所以我搜索了一个bash命令,递归地清理所有文件中的非法字符。用双引号文件进行批量重命名

我发现这个解决方案(https://stackoverflow.com/a/19009177/7394134):

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

它的工作对大多数文件,但它不包含双引号的文件工作和失败,出现以下错误信息:

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

我发现有点不同的问题lik e“删除含双引号的文件”或“用文件中的sed删除双引号”,但不幸的是我无法将他们的解决方案转移到上述命令的成功修改上。

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

回答

0

一种方法是在bash中涉及command-substitution$(..)的所有操作进行适当的双引号操作。如果不这样做,shell会将执行的命令的结果(如果结果包含空格/特殊字符)作为单独的单词处理。如果任何命令都对结果运行,错误很容易,因为不正确的论点(在可能的情况,可能是由于可变y不正确赋值)

低于因此,一个简单的技巧,双引号的sed命令像,

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

可以为你做的伎俩。

或者,如果你有兴趣在一个更防呆的方式来处理与在名称中包含特殊字符的文件,

GNU find使用-print0选项来处理文件名有特殊字符的文件/白的空间,与bashprocess-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命令返回,以便处理与白色空间/特殊字符和read-d$'\0')名称的末尾附加一个NULL角色,将来自输出find以\ 0作为解除限制器。