質問

I wrote this code and it works fine, it should find lines in which there's no string like 'SID' and append a pipe | at the beginning of the line, so like this: find all lines in which there's no 'SID' and append a pipe | at the beginning of the line. But how I wrote it, I can just output the lines which were changed and have a pipe. What I actually want: leave the file as it is and just append the pipes to the lines which match. Thank you.

#!usr/bin/perl
use strict;
use warnings;
use autodie;

my $fh;

open $fh, '<', 'file1.csv';
my $out = 'file2.csv';
open(FILE, '>', $out);

my $myline = "";
while (my $line = <$fh>) {
  chomp $line;
  unless ($line =~ m/^SID/) {
    $line =~ m/^(.*)$/;
    $myline = "\|$1";
  }
  print FILE $myline . "\n";
}

close $fh;
close FILE;

my file example:

SID,bla
foo bar  <- my code adds the pipe to the beginning of this line 

output should be like this:

SID,bla
| foo bar

but in my case I only print $myline, I know:

| foo bar
役に立ちましたか?

解決

The line

$line =~ m/^(.*)$/

is misguided: all it does is put the contents of $line into $1, so the following statement

$myline = "\|$1"

may as well be

$myline = "|$line"

(The pipe | doesn't need escaping unless it is part of a regular expression.)

Since you are printing $myline at the end of your loop you are never seeing the contents of unmodified lines.

You can fix that by printing $line or $myline according to which one contains the required output, like this

while (my $line = <$fh>) {
  chomp $line;
  if ($line =~ m/^SID/) {
    print "$line\n";
  }
  else {
    my $myline = "|$line";
    print "$myline\n";
  }
}

or, much more simply, by dropping the intermediate variable and using the default $_ for the input lines, like this

while (<$fh>) {
  print '|' unless /^SID/;
  print;
}

Note that I have also removed the chomp as it just means you have to put the newline back on the end of the string when you print it.

他のヒント

Instead of creating a new variable $myline, use the one you already have:

while (my $line =<$fh>) {
    $line = '|' . $line if $line !~ /^SID/;
    print FILE $line;
}

Also, you can use lexical filehandle for the output file as well. Moreover, you should check the return value of open:

open my $OUT, '>', $out or die $!;
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top