好吧,我要绕圈子了。我正在使用这个命令
find . -print0 -name '*.1.*' | sed -e 'p;s/\.1//' | xargs -0 -n2 mv
尝试重命名数百个带有“.1”的文件。在有人意外删除了 200GB 的数据后对其进行存档时,在文件扩展名之前添加了此内容。
我陷入了 mac xargs 将文件名中的空格解释为单独的参数,并且无法将分隔符设置为仅换行符,而不是空格之间。我不知道如何找到打印 '\0' 字符以及之间的换行符。关于如何让它发挥作用有什么想法吗?我一直在兜圈子里搜索,似乎只是在 mac 环境上让这变得比必要的更加复杂。
或者尝试重命名命令但仍然有问题
find . -name '*.1.*' -type f -exec rename -n 's/\.1//' '{}' \;
按照下面的@Wildcard 回答
find . -name '*.1.*' -type f -exec sh -c '
for f do
suf="${f##*.1}"
new="${f%.1.*}$suf"
if [ -e "$new" ]; then
printf "Cannot move file <%s>\n" "$new"
else
mv -n "$f" "$new"
fi
done
' find-sh {} +
答案1
以下内容应该始终安全并且应该在 Mac 上运行:
find . -name '*.1.*' -type f -exec sh -c '
for f do
suf="${f##*.1.}"
new="${f%.1.*}.$suf"
if [ -e "$new" ]; then
printf "Cannot move file <%s>\n" "$new"
else
mv -n "$f" "$new"
fi
done
' find-sh {} +
注意mv -n
出口成功地如果它会覆盖现有文件,则无需重命名该文件。您可能希望对此进行报道。所以这就是这样做的。
此外,在奇数边缘情况下,有目录使用目标新名称,mv
会将文件移入其中,而无需我添加的安全检查(即使使用-n
)。这也是不可取的。
.1.
如果文件名称中包含多个字符串,则此命令将仅删除最后一个字符串。 (这可能比删除第一的一个会是。)
-n
理论上,您根本不需要使用安全检查if
块进行开关,但我将其保留下来是为了在出现竞争条件时保护数据(如果其他进程在您将文件移动到该名称之上之前创建了一个目标文件) 。
最重要的是,无论你的文件名多么奇怪,这都不会爆炸。 即使它们嵌入了换行符、单引号字符、星号和各种其他内容。
不过仔细想想,我不是确定 bash 参数扩展在 Unicode 上的工作效果如何。