我的外部驱动器上有数百个文件,这些文件可能被复制了很多,并且也可能在某个时候恢复。文件名似乎在其生命周期中获得了一些奇怪的字符,我需要修复它们。
问题是我可以用 列出它们ls
,但我不能通过引用它们的名字来对它们做任何事情。
ls -l
呈现此结果:
-rwx------ 1 krzysztof staff 322451 Jun 27 2009 file015.jpg
-rwx------ 1 krzysztof staff 331337 Jun 27 2009 file016.jpg
-rwx------ 1 krzysztof staff 303078 Jun 27 2009 file017.jpg
-rwx------ 1 krzysztof staff 312346 Jun 27 2009 file018.jpg
文件本身没有损坏,如果我手动更改名称,问题就会消失。我还可以创建一个名称看似完全相同的文件(并且两者将同时显示ls
)。这让我相信隐形字符中存在一些可疑的情况,我通过运行确认了这一点find . -name '*[! -~]*'
- 它返回了所有有问题的文件的列表。
我通常不会关心这些名称,但某些应用程序和工具显然也对它们有问题,并且直接看不到它们或忽略它们。
一个例子是detox
我第一次尝试用来修复名称的工具 - 它只是假装它们不存在。
exiftool
抛出No such file or directory
。类似地,通过管道传输ls -1
到循环,或将文件名保存到文件中,然后通过管道传输它们总是会产生各种形式No such file or directory
。就像管道或保存时不保留不可见字符一样?
$ while read p; do
mv "$p" "$p"
done <`find . -name '*.jpg'`
zsh: no such file or directory: ./file015.jpg
有没有办法批量清理文件名?
编辑1:
根据 @terdon 的要求,我尝试了ls -v
,但ls -B
没有任何结果。
然而,这ls | head -n1 | od -c
更有趣,也让我有了自己的发现。在这里,我欠你一个道歉,因为在我最初的问题中,我改变了名字,因为我认为这并不重要,但事实确实如此。
这样,以下是实际输出,其中文件 014 已手动修复,其余部分已损坏:
❯ ls -1
Zdjęcie014.jpg
Zdjęcie015.jpg
Zdjęcie016.jpg
Zdjęcie017.jpg
Zdjęcie018.jpg
这是ls | head -n2 | od -c
- 我曾经n2
显示的不仅仅是第一个文件名。
❯ ls | head -n2 | od -c
0000000 Z d j e ̨ ** c i e 0 1 4 . j p g
0000020 \n Z d j e ̨ ** c i e 0 1 5 . j p
0000040 g \n
0000042
正如您所看到的,两个文件中都有一个ę
字符,并且在ls | head -n2 | od -c
.但!当我返回手动编辑和重命名文件时,在 014(固定文件)中,当我将光标放在后面ę
并按退格键时,整个字符消失。对于其他文件而言,情况并非如此 - 按退格键ę
会将其更改为e
,并且只有第二个退格键才会将其删除。
谢谢@terdon - 现在我们知道问题出在哪里了。如何批量修复此问题?
编辑2:
014 已修复,015 已损坏:
❯ ls | head -n2 | LC_ALL=C sed -n l
Zdje\314\250cie014.jpg$
Zdje\314\250cie015.jpg$
编辑3:
正如评论中所建议的,我尝试应用解决方案如何在 macOS 上重命名带有重音符号的文件名?但再次遇到No such file or directory
❯ rename $'s/\u119/e/g' ./*
Can't rename './Zdjęcie015.jpg' to './Zdjecie015.jpg': No such file or directory
rename $'s/\u0328//g' ./*
在 bash 和 zsh 中不执行任何操作
编辑4:
❯ PERL_UNICODE=ASD find . -depth -execdir rename -n 's/\pM//g' {} +
'Zdjęcie015.jpg' would be renamed to 'Zdjecie015.jpg'
和
❯ PERL_UNICODE=ASD find . -depth -execdir rename 's/\pM//g' {} +
Can't rename 'Zdjęcie015.jpg' to 'Zdjecie015.jpg': No such file or directory
答案1
我不确定这是否真的是一个答案,因为我无法使其在 macOS 上运行,但这确实是解决我的问题的解决方法。
由于外部驱动器是 NAS,因此我通过 ssh 进入它并直接解决了问题。不幸的是,我无法使用像这样的奇特工具rename
,所以我不得不使用find
,mv
和sed
- 并且它工作得恰到好处!
这是我使用的命令:
find ./ -maxdepth 1 -name "*.JPG" -exec sh -c 'mv "$1" "$(echo "$1" | sed s/Zdj.*cie/zdjecie/)"' _ {} \;
PS感谢评论区大侠一路以来的帮助!