在unix中使用perl从windows文件中删除新行
我正在RH5上使用perl 我有一个由Windows以以下格式输出的以空格分隔的文件: 24个头文件 A B1 C1 B2 C2 B3 C3 B4 C4 D E1 F1 E2F2 对于在gnuplot和WINDOWS上的其他绘图软件中使用(如果它在UNIX gnuplot上工作,则奖励点数),我希望它的形式为 A B1 C1 B2 C2 B3 C3 B4 C4 D E1 F1 E2 F2 在搜索stackoverflow后,我发现需要使用替换而不是chomp(),因为windows使用\r\n而不仅仅是\n。因此,我编写了这段代码在unix中使用perl从windows文件中删除新行,perl,gnuplot,Perl,Gnuplot,我正在RH5上使用perl 我有一个由Windows以以下格式输出的以空格分隔的文件: 24个头文件 A B1 C1 B2 C2 B3 C3 B4 C4 D E1 F1 E2F2 对于在gnuplot和WINDOWS上的其他绘图软件中使用(如果它在UNIX gnuplot上工作,则奖励点数),我希望它的形式为 A B1 C1 B2 C2 B3 C3 B4 C4 D E1 F1 E2 F2 在搜索stackoverflow后,我发现需要使用替换而不是chomp(),因为windows使用\r\n而
use strict;
use warnings;
my $filename = 'windowsfile.dat';
open (my $fh, '<:encoding(UTF-8)', $filename)
or die "Could not open file '$filename' $!"; #aborts if file does not exist
my $n = 0; #line number counter
while (my $row = <$fh>){
$n = $n + 1;
if ($n > 24){ #skip header files
if( ($n%4) != 0){ #Use modulus to take all but every 4th row.
$row =~ s/\r?\n/ /; #removes Windows or Unix newline at end of read data
#$row =~ s/\r/ /; #also tried this pair of commands
#chomp($row);
}
print "$row\n"; #<---- turned out this was the mistake.There should not be a \n.
}
}
使用严格;
使用警告;
我的$filename='windowsfile.dat';
打开(我的$fh,你可能更喜欢你的程序重构
use autodie
保存手动检查open
调用的状态
use open
设置所有标准和新打开的IO句柄的默认模式
while
循环通过使用默认的$\uu
保存输入行而变得更加简洁
- 有一个内置的行计数器
$。
,您也可以使用它
- 根据
$。%4
是否为零,可执行文件替换将所有尾随空格(包括CR和LF)更改为空格或换行符
local$/;$\u=$匹配=$\u;
$match=~s/(\w+)\r*\n*\s+/${1}/gs;
$match=~s/([A-Z])\s/\n$1/gs;
打印$match;
First guess:您的正则表达式只工作一次。您需要一个g修饰符:$row=~s/\r?\n//g;unix2dos
和dos2unix
可能也值得一看。print$row;
而不是print“$row\n”
?试试:$row=~s/\r\n]//g;而不是$row=~s/\r?\n/;感谢mpapec成为我的第二双眼睛!我完全错过了这一点。Sobrique,我将研究这些,它们听起来很有用。stackoverflow不鼓励使用纯代码答案。最好解释代码的作用以及它如何解决问题。这有助于未来的用户。
use strict;
use warnings;
use 5.010;
use autodie;
use open qw/ :std :encoding(UTF-8) /;
my $filename = 'windowsfile.dat';
open my $fh, '<', $filename;
while (<$fh>) {
next unless $. > 24;
s/\s+\z/ $. % 4 ? ' ' : "\n" /e;
print;
}
A B1 C1 B2 C2 B3 C3 B4 C4
D E1 F1 E2 F2
local $/; $_ = <DATA>; $match=$_;
$match=~s/(\w+)\r*\n*\s+/${1} /gs;
$match=~s/([A-Z])\s/\n$1 /gs;
print $match;