我想通过在每行的开头添加行号来修改文件。我发现以下命令执行此操作:
cat file | perl -pe '$_ = "$. $_"' > file_with_line_numbers
然而,这似乎有效,当我在vim中打开文件时,它充满了^ @和^ M个字符。进一步的调查显示编码已经改变。
> file -bi file
text/plain; charset=utf-16le
> file -bi file_with_line_numbers
application/octet-stream; charset=binary
我在这里缺少什么?
答案 0 :(得分:9)
因为您没有对输入数据进行解码,而且您没有对输出数据进行编码,并且通过将$.
与$_
连接起来,您混合了两种不同编码的数据(相反,你正在混合一个字节字符串和一个字符串,但是perl会隐式地将字节字符串转换为字符串,并以非常错误的方式为你所需要的方式进行操作。
一个解决方案是:
perl -pe 'BEGIN { binmode STDIN, ":encoding(utf16le)"; binmode STDOUT, ":encoding(utf16le)" } $_ = "$. $_";' < input > output
答案 1 :(得分:5)
您需要解码程序的输入并对程序的输出进行编码。
正如ysth所指出的,这将起到作用(除了在Windows上,但可能使用cygwin):
perl -Mopen=:std,':encoding(utf-16le)' -pe'$_="$. $_";' file.in >file.out
其余原始答案:
如果你有UTF-8,这是最容易的,因为你可以使用-CSDA
。
<file.in iconv -f UTF-16le -t UTF-8 \
| perl -CSDA -pe'$_="$. $_";' \
| iconv -f UTF-8 -t UTF-16le \
>file.out
由于UTF-8的属性,在这种情况下,您可以完全脱离而无需解码/编码,允许您使用以下任一项:
<file.in iconv -f UTF-16le -t UTF-8 \
| perl -pe'$_="$. $_";' \
| iconv -f UTF-8 -t UTF-16le \
>file.out
或
<file.in iconv -f UTF-16le -t UTF-8 \
| nl \
| iconv -f UTF-8 -t UTF-16le \
>file.out