nec*_*ciu 6 ls bash zsh unicode
在备份我的目录时,名称包含波兰语字符(如 \xc4\x99、\xc4\x85、\xc5\xbc、\xc5\xba 等)的目录被“重复”。
\n当我这样做时,ls -al
我得到如下回复:
drwxrwxr-x+ 310 root users 313 Oct 9 16:18 .\ndrwxrwxr-x+ 13 root users 14 Dec 1 2019 ..\ndrwxrwxr-x+ 2 root users 83 May 16 2021 '050805 - PKP Mi\xc4\x99dzyzdroje'\ndrwxrwxr-x+ 2 root users 83 Nov 8 2019 '050805 - PKP Mi\xc4\x99dzyzdroje'\n
Run Code Online (Sandbox Code Playgroud)\n但是,当我尝试对目录(例如ls
、 或mv
)执行某些操作时,zsh 会以不同的方式自动完成目录:
正确编码“\xc4\x99”的选项:ls 050805\\ -\\ PKP\\ Mi\xc4\x99dzyzdroje/
带有 4 符号 unicode 字符“<0328>”的选项:ls 050805\\ -\\ PKP\\ Mie<0328>dzyzdroje/
问题:如何找到包含这些 4 符号 unicode 字符的所有目录,以便将其重命名为某个 ASCII 名称,然后对它们进行重复数据删除?
\nFWIW,我的主机在 Debian 上,但我可能是通过 Samba 使用 macOS 客户端导致了这个问题。
\nSté*_*las 11
您有一些文件的\xc4\x99
预组合形式(U+0119 带有 OGONEK 的拉丁文小写字母 E)和一个其分解形式的文件,后跟e
U+0328 COMBINING OGONEK。
众所周知,macOS 会将文件名中的文本转换为分解形式,从而导致各种问题。
\n要查找包含 U+0328 字符的文件名,请使用zsh
:
ls -ld -- **/*$'\\u328'*(D)\n
Run Code Online (Sandbox Code Playgroud)\n或者找到那些带有任何组合标记的:
\nset -o rematchpcre\nls -ld -- **/*(De['[[ $REPLY:t =~ "\\pM" ]]'])\n
Run Code Online (Sandbox Code Playgroud)\n或者定义一个辅助函数:
\nhasMarks() {\n set -o localoptions -o rematchpcre\n [[ $REPLY:t =~ '\\pM' ]]\n}\nls -ld -- **/*(D+hasMarks)\n
Run Code Online (Sandbox Code Playgroud)\n要从分解转换为预组合,在任何类似 POSIX 的 shell 中并假设文件名不以换行符结尾:
\nprecomposed=$(printf '%s\\n' "$decomposed" | uconv -x nfc)\n
Run Code Online (Sandbox Code Playgroud)\n或者zsh
不必做出这样的假设:
printf -rN - $decomposed | uconv -x nfc | IFS= read -rd '' precomposed\n
Run Code Online (Sandbox Code Playgroud)\n(在Debian 上的包uconv
中)。icu-devtools
因此,要重命名它们,请在zsh
:
set -o rematchpcre -o pipefail\nfor file (**/*(NDode['[[ $REPLY:t =~ "\\pM" ]]']))\n print -rN - $file:t | uconv -x nfc | IFS= read -rd '' new &&\n mv -Tvi -- $file $file:h/$new\n
Run Code Online (Sandbox Code Playgroud)\n