我试图在Perl的每一个非空行的文本文件末尾添加"
开始和结束",
。
perl -pi -e 's/^(.+)$/\"$1\",/g' something.txt
它增加了"
在每个非空行的开始,但我有问题",
。
示例input:
bla bla bla blah
这是我得到的输出:
"bla ", "bla bla ", "blah ",
而这是我真正想要的输出 :
"bla", "bla bla", "blah",
我该如何解决?
编辑:我现在在vim打开我的输出文件(我之前打开它在kwrite之前,所以它是不可见的),我注意到vim在每个之前显示^M
",
– 我不知道在代码中增加了这一点。
看起来像一个行结束的问题 – 你在Windows中编辑文件? 尝试dos2unix
如果你不想使用dos2unix你可以匹配\ r:
perl -pi -e 's/^(.+)\r$/\"$1\",/g'
问题是,如果你在文件中有回报,它会匹配他们。*所以你会得到:
"bla^M", "bla bla^M", "blah^M",
您的数据文件必须源自Windows,它使用CRLF作为行分隔符而不是LF。 这意味着你的文本文件看起来像这样:
bla[CR][LF]bla bla[CR][LF]blah[CR][LF]
你可以使用od -c something.txt
来验证。
$ od -c something.txt 0000000 bla \r \nblabla \r \nbl 0000020 ah \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格式,然后您的脚本将按预期运行。
在使用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行结束符 – 这可能是也可能不是你想要的。
sed 's/.\{1,\}/"&",/'
这是在python或bash之前提出的- 在行尾添加“在行首”
既然你想在开始和结束时添加,你不需要用正则表达式替换这个简单的任务。
perl -ne 'chomp;print "\"".$_."\",\n"' file