bash 'fold' 搞砸了 emacs 中的编码

bash 'fold' screws up encoding in emacs

从 'somefile' 中读取行并将它们写入 'sample.org' 文件。

echo "$line" 1>>sample.org 给出了正确的结果,即“主观评分(从 1 到 5):4 - 优秀、清晰且味道浓郁..”(俄语字母 )

echo "$line" | fold -w 160 1>>sample.org 给出 this,如果您在 emacs 之外的任何地方复制粘贴,这在技术上是正确的。但还是。为什么使用 fold 会导致我的 emacs 在 'RAW-TEXT' 中显示 'sample.org' 缓冲区而不是 'UTF-8'

要重现它,请在同一目录中创建 2 个文件 - test.sh,其中将包含

cat 'test.org' |
  while read -r line; do
    # echo "$line" 1>'newfile.org' # works fine
    # line below writes those weird chars to the output file
    echo "$line" | fold -w 160 1>'newfile.org'
  done

test.org 文件,其中将仅包含“中发酵中稀半球乌龙卷”。 GABA 含量 200mg/100g.'

运行 带有 bash text.sh 的脚本,希望您会在输出文件 newfile.org

中看到问题

我不确定这些图像来自哪里,但是 foldcoreutils 通常,以及大量其他常见的 cli utils,只能安全地与包含的输入一起使用来自 Posix 可移植字符集的符号,而不是多字节 UTF-8,无论 utf8everywhere.org 之类的废话网站是什么状态。 fold 遇到常见问题 - 它假定每个符号只占用一个 char 导致多字节 UTF-8 输入在拆分行时被破坏。

我无法在 MacOS 上重现这个,但是在 Ubuntu Docker 图像中,这是因为 fold 在 UTF-8 多字节序列的中间插入了一个换行符.

root@ef177a152b15:/# cat test.org 
Среднеферментированный среднепрожаренный улун полусферической скрутки. Содержание ГАМК 200мг/100г.
root@ef177a152b15:/# fold -w 160 test.org >newfile.org
root@ef177a152b15:/# cat newfile.org 
Среднеферментированный среднепрожаренный улун полусферической скрутки. Содержание Г?
?МК 200мг/100г.
root@ef177a152b15:/# cat /etc/lsb-release 
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"

(也许还注意到您的演示脚本可以简化为一行。)

我原以为 GNU fold 可以识别区域设置,但您必须配置 UTF-8 区域设置才能激活支持;但这对我来说没有任何改变。

root@ef177a152b15:/# locale -a
C
C.UTF-8
POSIX
root@ef177a152b15:/# LC_ALL=C.UTF-8 fold -w 160 test.org 
Среднеферментированный среднепрожаренный улун полусферической скрутки. Содержание Г?
?МК 200мг/100г.

在这种情况下,我能提供的最好办法就是用一个简单的替换来替换 fold

#!/usr/bin/python3

from sys import argv

maxlen = int(argv.pop(1))

for file in argv[1:]:
    with open(file) as lines:
        for line in lines:
            while len(line) > maxlen:
                print(line[0:maxlen])
                line = line[maxlen:]
            print(line, end='')

为简单起见,这里没有任何选项处理;只需传入最大长度作为第一个参数。

(Python 3 在任何健全的平台上始终使用 UTF-8。不幸的是,这不包括 Windows;但我要重申显而易见的事实。)

Bash,当然,这里完全是无辜的; shell 不控制外部实用程序,如 fold。 (但也没有太大帮助;echo "${tekst:48:64}" 生成类似的拼音。)