我在 MX Linux 23.2 上使用 zsh。
多年来我一直试图弄清楚为什么像这样的命令
find . -depth -type f -execdir rename 's/_720p//' {} \;
跳过文件。
我知道我的文件管理器无法显示更改,因此我通过ls
在终端中输入进行检查。你瞧!那里列出了名称中仍带有“_720p”的文件。
我尝试将进程发送到后台并使用wait
,但我得到了相同的结果。我唯一发现的是类似的东西
while [ ! .(NF) ]; do
filename=$(find . -type f -print0 -quit)
rename 's/_720p//' $filename
mv $filename $HOME/Videos
done
我从来没有见过另一个问题与这个问题有一点相似。我是 Linux 宇宙中唯一一个做不到这一点的人吗?问题是什么?
答案1
s/_720p//
只替换第一次出现的内容_720p
,因此它将foo_720p_bar_720p
文件重命名为foo_bar_720p
.
您需要添加g
标志来替换每个出现的情况:s/_720p//g
,但即便如此,名为 example 的文件foo_72_720p0p
也只有一次出现,但一旦删除该出现,_720p
就会被重命名。foo_720p
在这种情况下,您需要while (s/_720p//g) {}
重试替换,直到找不到任何内容。
另请注意,某些基于 Perl 的rename
实现可以-d
选择仅对文件的基本名称进行操作,这样就不必为rename
每个文件运行一个了
find . -depth -name '*_720p*' -type f -exec rename -d '
while (s/_720p//g) {}' {} +
请注意,自动加载函数zsh
中内置了批量重命名器zmv
:
autoload -Uz zmv
zmv '(**/)(*_720p*)(#q.)' '$1$2:gs/_720p//'
将替换所有出现的情况。处理_72_72_720p0p0p
案件:
zmv '(**/)(*_720p*)(#q.)' '$1$2:fs/_720p//'
凡是f
造成以下情况的s
修饰语重复直到没有修改为止。
1 但不会从 的安全性改进中受益-execdir
。请注意,某些find
实现也支持{} +
,-execdir
尽管它仍然需要每个目录至少运行一个rename
。