tr -s 无法压缩连续空格

tr -s fails to compress consecutive spaces

这是我试图操作的文本文件的片段:

845136006577              1.0
845136006638              4.0
845136006676              6.0
845136007895              3.0
845136007970              7.0
845136008052              9.0
845136008175              4.0
845136008298              4.0
845136008373              4.0
845136008410              4.0
845136008557              3.0
845136008595              4.0

我试图将每一行的所有空格压缩为一个 ,(逗号)。

这是我尝试过的:

tr -s '[:space:]' ',' < file.txt

tr -s ' ' ',' < file.txt

但输出总是这样:

845136006577,,,,,,,,,,,,,,1.0,
845136006638,,,,,,,,,,,,,,4.0,
845136006676,,,,,,,,,,,,,,6.0,
845136007895,,,,,,,,,,,,,,3.0,
845136007970,,,,,,,,,,,,,,7.0,
845136008052,,,,,,,,,,,,,,9.0,
845136008175,,,,,,,,,,,,,,4.0,
845136008298,,,,,,,,,,,,,,4.0,
845136008373,,,,,,,,,,,,,,4.0,

我的文件是否存在编码问题?有点不对。

更新

xxd < file.txt 的输出片段:

00003b0: 3600 3000 3000 3800 3500 3500 3700 2000  6.0.0.8.5.5.7. .
00003c0: 2000 2000 2000 2000 2000 2000 2000 2000   . . . . . . . .
00003d0: 2000 2000 2000 2000 2000 3300 2e00 3000   . . . . .3...0.
00003e0: 2000 0a00 3800 3400 3500 3100 3300 3600   ...8.4.5.1.3.6.
00003f0: 3000 3000 3800 3500 3900 3500 2000 2000  0.0.8.5.9.5. . .
0000400: 2000 2000 2000 2000 2000 2000 2000 2000   . . . . . . . .
0000410: 2000 2000 2000 2000 3400 2e00 3000 2000   . . . .4...0. .
0000420: 0a00 3800 3400 3500 3100 3300 3600 3000  ..8.4.5.1.3.6.0.
0000430: 3000 3800 3600 3900 3400 2000 2000 2000  0.8.6.9.4. . . .
0000440: 2000 2000 2000 2000 2000 2000 2000 2000   . . . . . . . .
0000450: 2000 2000 2000 3500 2e00 3000 2000 0a00   . . .5...0. ...
0000460: 3800 3400 3500 3100 3300 3600 3000 3000  8.4.5.1.3.6.0.0.

您的输入编码为 UTF-16(或 UCS-2),但您读取它时就好像它是 ASCII(或 UTF-8、ISO-8859 或类似的)一样,因此您会看到替代的 ASCII 和空值。

所以这些空格看起来都是用 NUL 分隔的,不会合并。

一种解决方法是通过 iconv 管道并返回(假设您希望结果采用相同的编码):

iconv -f utf-16 -t utf-8 \
    | tr -s '[:blank:]' ',' \
    | iconv -f utf-8 -t utf-16

显然,如果您希望输出为 UTF-8,则可以跳过最后的重新编码步骤。

您无法使 tr 或其他标准实用程序在本地使用 UTF-16 或 UCS-2,因此如果您不想更改为 Perl 或 Python.

由于文件中充满了空字符,您可以在使用 tr 处理之前删除它们(假设您不希望其中有任何空字符)。

用 tr 两次

tr -d '[=10=]' < file | tr -s '[:blank:]' ','

使用单个 perl

perl -pe 's/\x00//g;s/[[:blank:]]+/,/' file

或者如果您想保留编码

perl -pe 's/([[:blank:]]\x00)+/,\x00/g' file

或者可能最稳健的是,您可以设置 perl 的编码来读取。

perl -Mopen=":std,:encoding(utf-16le)" -pe 's/[[:blank:]]+/,/g' test