开发者

Perl: extract rows from 1 to n (Windows)

I want to extract rows 1 to n from my .csv file. Using this

perl -ne 'if ($. == 3) {print;exit}' infile.txt 

I can extract only开发者_如何学运维 one row. How to put a range of rows into this script?


If you have only a single range and a single, possibly concatenated input stream, you can use:

#!/usr/bin/perl -n
if (my $seqno = 1 .. 3) {
    print;
    exit if $seqno =~ /E/;
}

But if you want it to apply to each input file, you need to catch the end of each file:

#!/usr/bin/perl -n
print if my $seqno = 1 .. 3;
close ARGV if eof || $seqno =~ /E/;

And if you want to be kind to people who forget args, add a nice warning in a BEGIN or INIT clause:

#!/usr/bin/perl -n
BEGIN { warn "$0: reading from stdin\n" if @ARGV == 0 && -t }
print if my $seqno = 1 .. 3;
close ARGV if eof || $seqno =~ /E/;

Notable points include:

  • You can use -n or -p on the #! line. You could also put some (but not all) other command line switches there, like ‑l or ‑a.

  • Numeric literals as operands to the scalar flip‐flop operator are each compared against readline counter, so a scalar 1 .. 3 is really ($. == 1) .. ($. == 3).

  • Calling eof with neither an argument nor empty parens means the last file read in the magic ARGV list of files. This contrasts with eof(), which is the end of the entire <ARGV> iteration.

  • A flip‐flop operator’s final sequence number is returned with a "E0" appended to it.

  • The -t operator, which calls libc’s isatty(3), default to the STDIN handle — unlike any of the other filetest operators.

  • A BEGIN{} block happens during compilation, so if you try to decompile this script with ‑MO=Deparse to see what it really does, that check will execute. With an INIT{}, it will not.

  • Doing just that will reveal that the implicit input loop as a label called LINE that you perhaps might in other circumstances use to your advantage.

HTH


What's wrong with:

head -3 infile.txt

If you really must use Perl then this works:

perl -ne 'if ($. <= 3) {print} else {exit}' infile.txt 


You can use the range operator:

perl -ne 'if (1 .. 3) { print } else { last }' infile.txt
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜