使用perl从unix中的windows文件中删除新行

时间:2014-11-13 16:20:35

标签: perl gnuplot

我在RH5上使用perl。

Windows以这种格式输出了空格分隔文件:

  

24个头文件

     

A B1 C1

     

B2 C2

     

B3 C3

     

B4 C4

     

D E1 F1

     

E2 F2 ......

用于gnuplot和其他绘图软件ON WINDOWS(如果它适用于UNIX gnuplot,奖励积分),我希望它在表单中。

  

A B1 C1 B2 C2 B3 C3 B4 C4

     

D E1 F1 E2 F2 ......

在我搜索stackoverflow之后,我发现需要使用替换而不是chomp(),因为windows使用\ r \ n而不是仅使用\ 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.
    } 

}

这不起作用。当我在VIM for Windows上查看文件时,我看到:

  

A B1 C1

     

B2 C2

     

B3 C3

     

B4 C4 ^ M

当我在Unix上查看gedit时,我也看到了原始格式。当我尝试绘制数据时,在Windows上的gnuplot中,我得到一个没有数据发现错误。当我在UNIX上使用gnuplot绘制它时,它会像所有回车仍然存在一样绘制。我猜我的部分问题是在平台之间切换,但我不明白为什么我的代码实际上并没有阻止新行发生。

或者,如果你能告诉我如何绘图 使用当前格式的gnuplot中的vs B1和A vs C4,这将是有用的。 perl解决方案很不错,因为它在各种情况下更容易,例如A与C4-B2或在其他软件中使用。

2 个答案:

答案 0 :(得分:1)

您可能更喜欢这个重构程序。

  • use autodie保存手动检查open来电的状态

  • use open设置所有标准和新打开的IO句柄的默认模式

  • 使用默认while来保存输入行,使$_循环更简洁

  • 您可以使用内置行计数器$.

  • 根据$. % 4是否为零,可执行替换将所有尾随空格(包括CR和LF)更改为空格或换行符。

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  

答案 1 :(得分:0)

local $/; $_ = <DATA>; $match=$_;
$match=~s/(\w+)\r*\n*\s+/${1} /gs;
$match=~s/([A-Z])\s/\n$1 /gs;
print $match;