Perl(或其他) - ^ M问题

时间:2009-12-02 22:12:14

标签: linux perl

我正在尝试在开头添加",在Perl中每个非空行文本文件末尾添加",

perl -pi -e 's/^(.+)$/\"$1\",/g' something.txt

它会在每个非空行的开头添加",但我对",有疑问。

示例输入:

bla
bla bla
blah

这是我得到的输出:

"bla
",
"bla bla
",
"blah
",

那是输出我真的想要

"bla",
"bla bla",
"blah",

我该如何解决这个问题?

编辑: 我现在在vim中打开输出文件(我之前在kwrite中打开它,因此它不可见)并且我注意到每个^M之前的vim显示", - 我不知道代码中添加了什么

5 个答案:

答案 0 :(得分:5)

看起来像行结束问题 - 你在Windows中编辑文件了吗?尝试 dos2unix

如果您不想使用dos2unix,则可以匹配\ r:

perl -pi -e 's/^(.+)\r$/\"$1\",/g'

问题是,如果你在文件中有回复,它将匹配它们。*所以你会得到:

"bla^M",
"bla bla^M",
"blah^M",

答案 1 :(得分:2)

您的数据文件必须源自Windows,它使用CRLF作为行分隔符而不仅仅是LF。这意味着您的文本文件如下所示:

bla[CR][LF]bla bla[CR][LF]blah[CR][LF]

您可以使用od -c something.txt对此进行验证。

$ od -c something.txt
0000000    b   l   a  \r  \n   b   l   a       b   l   a  \r  \n   b   l
0000020    a   h  \r  \n                                                
0000024

在Unix或Linux下,它将如下所示:

bla\r
bla bla\r
blah\r

当perl进行替换时,会产生以下结果:

"bla\r",
"bla bla\r",
"blah\r",

当你得到结果时,你会得到你所看到的:

"bla
",
"bla bla
",
"blah
",

最简单的方法是使用dos2unix将行结尾转换为Unix格式,然后您的脚本将按预期运行。

答案 2 :(得分:1)

在使用CRLF文本文件的系统上,Perl使用IO层将CRLF过滤到我们在脚本中只看到LF的过程。但是,如果在不正常使用CRLF的系统上打开CRLF文件,则可以通过多种方式启用CRLF转换。

您可以使用binmode。我在这里使用OO界面,因为我认为它更干净,YMMV:

use IO::File;

open( my $fh, '<', 'winfile.txt' ) 
    or die "Oh poo - $!\n";

$fh->binmode(':crlf');

你也可以使用调整打开:

open( my $fh, '<:crlf', 'winfile.txt' ) 
    or die "Oh poo - $!\n";

或者对于您的单行,您可以设置PERLIO环境变量(请参阅PerlIO):

PERLIO=crlf perl -pi -e 's/^(.+)$/\"$1\",/g' something.txt

当然,这种方法会保留处理文件中的CRLF行结尾 - 这可能是您想要的,也可能不是。

答案 3 :(得分:0)

sed 's/.\{1,\}/"&",/'

python or bash - adding " at beginning of line and ", at end of line

之前询问了这个问题

答案 4 :(得分:0)

因为要在开头和结尾添加,所以不要对该简单任务进行正则表达式替换。

perl -ne 'chomp;print "\"".$_."\",\n"' file