【问题标题】:tr [:upper:] [:lower:] with Cyrillic texttr [:upper:] [:lower:] 带有西里尔文字
【发布时间】:2012-11-14 15:25:07
【问题描述】:

我正在尝试从俄罗斯短篇小说中提取单词列表。

#!/bin/sh

export LC_ALL=ru_RU.utf8

sed -re 's/\s+/\n/g' | \
sed 's/[\.!,—()«»;:?]//g' | \
tr '[:upper:]' '[:lower:]' | \
sort | uniq

但是,tr 步骤不会将西里尔大写字母小写。我认为我使用可移植字符类很聪明!

$ LC_ALL=ru_RU.utf8 echo "Г" | tr [:upper:] [:lower:]
Г

如果相关,我通过从 Chrome 浏览器窗口复制粘贴到 Vim 中获得了俄语文本。它在屏幕上看起来很正确(Putty 终端)。这是在 Cygwin 的 bash shell 中——它应该与 Linux 上的 Bash 相同(应该!)。

什么是在管道中小写 unicode 文本的可移植、可靠的方法?

【问题讨论】:

  • sed 的转换对我有用:echo 'СТЭК' | sed 's/[[:upper:]]*/\L&/'
  • echo "Г" | tr [:upper:] [:lower:] 在 Mac OS X 10.8 系统上正确输出“г”。
  • 谢谢@LevLevitsky。这对我来说是一个合适的解决方案(随时将其推广为答案)。我想知道为什么 tr 不起作用。
  • @ulidtko 有意思,tr 是什么版本的?
  • OSX tr 是 BSD tr。手册页说历史上 LC_ALL 被忽略了,现在不是了。我想这意味着支持 unicode。 developer.apple.com/library/mac/#documentation/Darwin/Reference/…

标签: shell unicode tr


【解决方案1】:

这是我在Wikipedia 找到的(但没有任何参考):

tr 的大多数版本,包括 GNU tr 和经典的 Unix tr,都对单字节字符进行操作,并且不兼容 Unicode。一个例外是 Heirloom Toolchest 实现,它提供基本的 Unicode 支持。

另外,this 是旧的但相关的。

正如我在评论中提到的,sed 似乎有效(至少GNU sed):

$ echo 'СТЭК' | sed 's/[[:upper:]]*/\L&/'
стэк

【讨论】:

  • 是的,单字节问题是真的。我曾经将此作为一个错误报告给 GNU,他们解释说这是设计使然(即他们必须破坏与旧软件的兼容性才能修复它)。我还在邮件列表中讨论过它,同样是told it was supposed to be that way
  • 如果要替换所有匹配项,请记住在正则表达式中添加 g 标志。
  • 如果在开头添加空格,则不会起作用:echo ' СТЭК' | sed 's/[[:upper:]]*/\L&/' => 'СТЭК'。似乎这个效果更好:echo ' СТЭК' | sed 's/.*/\L&/' => 'стэк'。在 GNU bash 版本 4.4.12(1)-release (x86_64-pc-linux-gnu) 上测试
  • 只需要加上g:'s/[[:upper:]]*/\L&/g'
【解决方案2】:

这对我有用:

echo ЫЕРУНКЫКТ | sed -e 's/\(.*\)/\L\1/'

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-22
    • 1970-01-01
    • 2022-12-03
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2013-06-02
    • 1970-01-01
    相关资源
    最近更新 更多