sus*_*tus 28 shell bash character-encoding find filenames
在一个80GB大小的大约700,000个文件的目录中,有些文件名的文件名中含有非英文字符。除了费力地浏览文件列表之外,还有:
man ascii(以便我可以测试这些文件是否被识别)?Lek*_*eyn 41
假设“foreign”表示“not an ASCII character”,那么您可以使用find模式来查找名称中没有可打印ASCII字符的所有文件:
LC_ALL=C find . -name '*[! -~]*'
Run Code Online (Sandbox Code Playgroud)
(空格是http://www.asciitable.com/ 上列出的第一个可打印字符,~是最后一个。)
提示 forLC_ALL=C是必需的(实际上LC_CTYPE=C和LC_COLLATE=C),否则字符范围会被错误地解释。另请参阅手册页glob(7)。由于LC_ALL=C原因find将字符串解释为 ASCII,它会将多字节字符(例如?)打印为问号。要解决此问题,请通过管道连接到某个程序(例如cat)或重定向到文件。
除了指定字符范围外,[:print:]还可用于选择“可打印字符”。一定要设置 C 语言环境,否则你会得到相当(看似)任意的行为。
例子:
$ touch $(printf '\u03c0') "$(printf 'x\ty')"
$ ls -F
dir/ foo foo.c xrestop-0.4/ xrestop-0.4.tar.gz ?
$ find -name '*[! -~]*' # this is broken (LC_COLLATE=en_US.UTF-8)
./x?y
./dir
./?
... (a lot more)
./foo.c
$ LC_ALL=C find . -name '*[! -~]*'
./x?y
./??
$ LC_ALL=C find . -name '*[! -~]*' | cat
./x y
./?
$ LC_ALL=C find . -name '*[![:print:]]*' | cat
./x y
./?
Run Code Online (Sandbox Code Playgroud)
如果使用翻译每个文件名tr -d '[\200-\377]'并将其与原始名称进行比较,则任何具有特殊字符的文件名都将不同。
(以上假设您的意思是非 ASCII 与外国)