好吧,我只是想去掉文件名中的双引号。这是我想出的命令(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
.然后,您可以在删除其中一个目录之前验证这两个目录的一切是否正常 - 毕竟它们几乎是相同的目录,除了在一个目录中没有包含"
.