将perl文件中的前两个字符提取到另一个文件

时间:2015-08-18 23:31:16

标签: bash perl

我在下面的代码中遇到了一些麻烦 - 我正在试图弄清楚如何打开所有这些文本文件(.cs以。结尾的文件都有一行他们)并从中获取前两个字符(这些都是数字)并将它们打印到另一个同名的文件中,后缀为“.number”。其中一些.DIS文件中没有任何内容,在这种情况下我想打印“0”。

最后,我想浏览每个原始.DIS文件并删除前3个字符 - 我是通过bash完成的。

my @DIS = <*.DIS>; 
foreach my $file (@DIS){
    my $name = $file;
    my $output = "$name.number";
    open(INHANDLE, "< $file") || die("Could not open file"); 
    while(<INHANDLE>){
        open(OUT_FILE,">$output") || die; 
        my $line = $_;
        chomp ($line);
        my $string = $line;
        if ($string eq ""){  
        print "0";      
        } else {
        print substr($string,0,2);
        }   
    }
    system("sed -i 's/\(.\{3\}\)//' $file");  
}

当我运行此代码时,我得到一个数字列表连接在一起并清空.DIS.number文件。我对Perl很新,所以任何帮助都会受到赞赏!

3 个答案:

答案 0 :(得分:1)

  

当我运行此代码时,我得到一个数字列表连接在一起并清空.DIS.number文件。

这是因为这条线。

print substr($string,0,2);

print默认打印到STDOUT(即屏幕)。你需要给它文件句柄打印到。

print OUT_FILE substr($string,0,2);

他们正在被连接,因为print只打印你告诉它的内容,它不会为你添加换行符(有一些global variables which can change this,不要乱用它们)。你必须自己添加换行符。

print OUT_FILE substr($string,0,2), "\n";

最后请注意,在使用Perl中的文件时,我建议使用lexical filehandlesPath::Tinyautodie。它们将避免在Perl中使用文件时出现大量经典问题。

答案 1 :(得分:0)

我建议你这样做

打开每个*.dis文件,并将内容读入$text。然后使用正则表达式替换从字符串中删除前三个字符并捕获$1中的前两个字符

如果替换成功,则$1的内容将写入数字文件,否则原始文件为空(或短于两个字符),而是写入零。然后将$text的剩余内容写回*.dis文件

use strict;
use warnings;
use v5.10.1;
use autodie;

for my $dis_file ( glob '*.DIS' ) {

    my $text = do {
        open my $fh, '<', $dis_file;
        <$fh>;
    };

    my $num_file = "$dis_file.number";

    open my $dis_fh, '>', $dis_file;
    open my $num_fh, '>', $num_file;

    if ( defined $text and $text =~ s/^(..).?// ) {
        print $num_fh "$1\n";
        print $dis_fh $text;
    }
    else {
        print $num_fh "0\n";
        print $dis_fh "-\n";
    }
}

答案 2 :(得分:-1)

这个awk脚本将每个文件的前两个字符提取到它自己的文件中。根据规范,空文件应该有一个空行。

awk 'FNR==1{pre=substr($0,1,2);pre=length(pre)==2?pre:0; print pre > FILENAME".number"}' *.DIS

这将删除前3个字符

cut -c 4-

Bash for循环将更好地做到这两点,我们需要稍微修改awk脚本

for f in *.DIS; 
do awk 'NR==1{pre=substr($0,1,2);$0=length(pre)==2?pre:0; print}' $f > $f.number; 
cut -c 4- $f > $f.cut; 
done

解释:遍历* .DTS中的所有文件,对于每个文件的第一行,尝试获取行的前两个字符(1,2)($ 0)分配给pre。如果pre的长度不是2(行是空的或只有1个字符),则将行设置为0或者使用pre;打印行,输出文件名将是附加.number后缀的输入文件。 $ 0赋值是保存几次键击的技巧,因为没有参数的print会打印$ 0,否则你可以提供参数。

理想情况下,您应引用“$ f”,因​​为它可能在文件名中包含空格......