Perl:从1到n提取行(Windows)

3
我想从我的 .csv 文件中提取第 1 到第 n 行。使用以下方法:
perl -ne 'if ($. == 3) {print;exit}' infile.txt 

我只能提取一行数据。如何将多行数据范围放入此脚本中?


可能是重复的问题:如何使用Perl从第n行开始写入文件 - Ether
3个回答

11

如果您只有一个范围和一个可能是连接的输入流,您可以使用以下方法:

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

但是如果你想将其应用于每个输入文件,你需要捕获每个文件的结尾:

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

如果你想对那些忘记参数的人友善一些,在BEGININIT子句中添加一个友好的警告:

#!/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/;

值得注意的几点包括:
  • 您可以在 #! 行上使用 -n-p。您还可以在那里放置一些(但不是全部)其他命令行开关,例如 ‑l‑a

  • 作为标量翻转操作符的操作数的数字文字将与 readline 计数器进行比较,因此标量 1 .. 3 实际上是 ($. == 1) .. ($. == 3)

  • 调用 eof 既没有参数也没有空括号,表示最后一个文件在文件列表中的 magic ARGV 中读取。这与 eof() 相反,它是整个 <ARGV> 迭代的结尾。

  • 翻转操作符的最终序列号带有附加的 "E0" 返回。

  • -t 操作符调用 libc 的 isatty(3),默认为 STDIN 句柄 - 不像任何其他文件测试操作符。

  • BEGIN{} 块在编译时发生,因此如果您尝试使用 ‑MO=Deparse 反编译此脚本以查看它实际上执行了什么,那个检查将会被执行。而对于 INIT{},则不会。

  • 仅这样做将揭示隐式输入循环作为称为 LINE 的标签,您或许可以在其他情况下利用它。

希望这有所帮助


2
你可以使用范围操作符:
perl -ne 'if (1 .. 3) { print } else { last }' infile.txt

2

以下是问题所在:

head -3 infile.txt

如果你非常需要使用Perl,那么这个方法可以解决问题:
perl -ne 'if ($. <= 3) {print} else {exit}' infile.txt 

我认为head命令在Windows上没有安装cygwin会出现问题。 - aschepler
2
perl -wpe'1..3 or exit' infile.txt - ysth
1
@ysth,我的例子的重点不是编写最简短的Perl代码,而是展示基于行号的条件处理的更通用的示例。 - Alnitak
所以 ysth 向您展示了“基于行号的条件处理的最通用方式”。 - Hynek -Pichi- Vychodil
不是,我的代码展示了如何“做a或做b”。他的代码只有“打印或退出”。 - Alnitak

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接