find、xargs 和 mv:使用双引号重命名文件、扩展和 bash 优先级问题

find、xargs 和 mv:使用双引号重命名文件、扩展和 bash 优先级问题

好吧,我只是想去掉文件名中的双引号。这是我想出的命令(bash)。

$ find . -iname "*\"*" -print0 | xargs -0 -I {} mv {} {} | tr -d \"

问题出在'mv {} {} | tr -d \"'零件上。我认为这是一个优先级问题: bash 似乎被解释为(mv {} {}) | tr -d \"),而我剩下的都是去掉双引号的文件名。显然,这不是我想要的,因为那样它就无法重命名该文件。相反,我希望第一个文件名包含引号,第二个文件名不包含引号,更像是这样:mv {} ({} | tr -d \").

我该如何实现这个目标?我已经尝试过方括号和大括号,但我不太确定在显式设置命令执行优先级时我在做什么。

答案1

假设您已rename安装该命令,请使用:

find . -name '*"*' -exec rename 's/"//g' {} +

rename命令采用Perl表达式来生成新名称。s/"//g执行名称的全局替换,用空字符串替换所有引号。

为此,mv您需要通过管道连接到 shell 命令,以便可以执行子命令:

find . -name '*"*' -exec sh -c 'mv "$0" "$(printf %s "$0" | tr -d "\"")"' {} \;

xargs您编写的内容通过管道传递to的输出tr,它不用于tr形成 to 的参数mv

答案2

xargs -0 -I {} mv {} {} | tr -d \"

没有意义:mv不产生输出。因此,您无法使用mv.

find . -name '*"*' -exec bash -c 'mv "$1" "${1//\"/}"' bash {} \;

或者以更少的开销

find . -name '*"*' -exec bash -c 'for file in "$@"; do mv "$file" "${file//\"/}"; done' bash {} +

答案3

你可能会做...

mkdir ../_cp
pax -Xwrl -s'/"//gp' . "${PWD%/*}/_cp"

这只是创建了一堆指向.../_cp.然后,您可以在删除其中一个目录之前验证这两个目录的一切是否正常 - 毕竟它们几乎是相同的目录,除了在一个目录中没有包含".

相关内容