如何查找包含 4 个符号 unicode 字符的目录,例如 `<0328>`

nec*_*ciu 6 ls bash zsh unicode

在备份我的目录时,名称包含波兰语字符(如 \xc4\x99、\xc4\x85、\xc5\xbc、\xc5\xba 等)的目录被“重复”。

\n

当我这样做时,ls -al我得到如下回复:

\n
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 会以不同的方式自动完成目录:

\n
    \n
  1. 正确编码“\xc4\x99”的选项:ls 050805\\ -\\ PKP\\ Mi\xc4\x99dzyzdroje/

    \n
  2. \n
  3. 带有 4 符号 unicode 字符“<0328>”的选项:ls 050805\\ -\\ PKP\\ Mie<0328>dzyzdroje/

    \n
  4. \n
\n

问题:如何找到包含这些 4 符号 unicode 字符的所有目录,以便将其重命名为某个 ASCII 名称,然后对它们进行重复数据删除?

\n

FWIW,我的主机在 Debian 上,但我可能是通过 Samba 使用 macOS 客户端导致了这个问题。

\n

Sté*_*las 11

您有一些文件的\xc4\x99预组合形式(U+0119 带有 OGONEK 的拉丁文小写字母 E)和一个其分解形式的文件,后跟eU+0328 COMBINING OGONEK。

\n

众所周知,macOS 会将文件名中的文本转换为分解形式,从而导致各种问题。

\n

要查找包含 U+0328 字符的文件名,请使用zsh

\n
ls -ld -- **/*$'\\u328'*(D)\n
Run Code Online (Sandbox Code Playgroud)\n

或者找到那些带有任何组合标记的:

\n
set -o rematchpcre\nls -ld -- **/*(De['[[ $REPLY:t =~ "\\pM" ]]'])\n
Run Code Online (Sandbox Code Playgroud)\n

或者定义一个辅助函数:

\n
hasMarks() {\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 中并假设文件名不以换行符结尾:

\n
precomposed=$(printf '%s\\n' "$decomposed" | uconv -x nfc)\n
Run Code Online (Sandbox Code Playgroud)\n

或者zsh不必做出这样的假设:

\n
printf -rN - $decomposed | uconv -x nfc | IFS= read -rd '' precomposed\n
Run Code Online (Sandbox Code Playgroud)\n

(在Debian 上的包uconv中)。icu-devtools

\n

因此,要重命名它们,请在zsh

\n
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