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

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

在备份我的目录时,名称包含 ę、ą、ż、ź 等波兰语字符的目录被“重复”。

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

drwxrwxr-x+ 310 root users     313 Oct  9 16:18  .
drwxrwxr-x+  13 root users      14 Dec  1  2019  ..
drwxrwxr-x+   2 root users      83 May 16  2021 '050805 - PKP Międzyzdroje'
drwxrwxr-x+   2 root users      83 Nov  8  2019 '050805 - PKP Międzyzdroje'

但是,当我尝试对目录执行某些操作(例如lsmv)时,zsh 会以不同的方式自动完成目录:

  1. 带有正确编码的“ę”的选项:ls 050805\ -\ PKP\ Międzyzdroje/

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

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

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

答案1

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

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

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

ls -ld -- **/*$'\u328'*(D)

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

set -o rematchpcre
ls -ld -- **/*(De['[[ $REPLY:t =~ "\pM" ]]'])

或者定义一个辅助函数:

hasMarks() {
  set -o localoptions -o rematchpcre
  [[ $REPLY:t =~ '\pM' ]]
}
ls -ld -- **/*(D+hasMarks)

要从分解转换为预组合,在任何类似 POSIX 的 shell 中并假设文件名不以换行符结尾:

precomposed=$(printf '%s\n' "$decomposed" | uconv -x nfc)

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

printf -rN - $decomposed | uconv -x nfc | IFS= read -rd '' precomposed

(在 Debian 上的包uconvicu-devtools)。

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

set -o rematchpcre -o pipefail
for file (**/*(NDode['[[ $REPLY:t =~ "\pM" ]]']))
  print -rN - $file:t | uconv -x nfc | IFS= read -rd '' new &&
    mv -Tvi -- $file $file:h/$new

相关内容