我想通过在每行的开头添加行号来修改文件。 我发现以下命令执行此操作:
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
我在这里错过了什么?
你需要解码你的程序的输入和编码你的程序的输出。
正如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
因为你没有解码你的输入数据,也没有编码你的输出数据,并且连接了$.
用$_
来混合使用两种不同编码的数据(而不是混合一个字节串和一个字符串,但是perl会隐式地把字节串转换成一个字符串,方式为你所需要的)。
一个解决办法是:
perl -pe 'BEGIN { binmode STDIN, ":encoding(utf16le)"; binmode STDOUT, ":encoding(utf16le)" } $_ = "$. $_";' < input > output