在文件中选择大量(特定)行

时间:2014-10-31 08:52:57

标签: perl unix sed

我想从大文件中选择大量特定行。

使用perl,我正在创建一个这种样式的命令(这里打印第2行和第4行):

sed -n -e 2p -e 4p $file

使用system()命令启动它。

这种方法很好,除非从文件中选择的行数变得非常大。它目前可以使用大约10,000行,但不能用于我想要选择~17,000行的另一个文件。可以传递给sed的参数数量是否有限制?是否有可供使用的替代UNIX工具? 谢谢你的帮助

4 个答案:

答案 0 :(得分:3)

您肯定必须在文件中包含您想要的行列表,因此我们假设该文件名为lines.txt,如下所示:

1
2
4
7

现在,你可以这样做:

awk 'FNR==NR{wanted[$0]++;next} FNR in wanted' lines.txt file

这说明...... FNR==NR表示第一组花括号仅适用于lines.txt文件的处理,在处理时,存储在数组wanted[]中您想要的行号,然后移动到下一行。第二部分FNR in wanted适用于处理名为file的第二个文件。它说,如果行号(FNR)在数组wanted[]中,则打印该行。

答案 1 :(得分:2)

这不是sed限制,而是bash命令行长度限制:最大getconf ARG_MAX字节(在Linux上我看到此值的值从131072到2621440)。

RenéNyffenegger的评论是明智的:在* NIX世界中,Perl是这类问题的更好选择......

如果您描述了如何选择要提取的行(例如:从i到j?或特定行的列表?,某些不同的逻辑?),应该很容易为您提供代码示例。

<强>更新 下面我给你一个第一个用例的例子。当然,如果你给出一些用例的例子,如果可以找到一个模式,那么应该很容易简化第二个更通用的用例的解决方案......

#!/usr/bin/perl
#
# Print a range of lines from a text file.
# Usage: extract-a-range-of-lines.pl first-line last-line input-file

# use ARGV to verify the number of perl command line arguments
@ARGV == 3 or die "Usage: $0 first-line last-line input-file\n";
my ($first_line, $last_line, $filename) = @ARGV;

open(my $FILE, "<", $filename) or die "Could not read from $filename ($!)"; # open the input file   
# loop through the input file
my $count = 1;
while (<$FILE>) {
  last if ($count > $last_line); # break loop when you get to the last line   
  print $_ if ($count >= $first_line); # print the current line if the line number is greater than first param
  $count++; # increment the line counter
}
close $FILE; # close input file

答案 2 :(得分:1)

以下是使用awk

的一种方法
awk 'NR~"^(2|8|12)$"' file

这将打印行2812


将行2打印到712

awk 'NR>=2 && NR<8 || NR==12' file

awk 'NR~"^([2-7]|12)$"' file

答案 3 :(得分:1)

一个sed命令:

使用;分隔符而不是多个-e 2p

sed -n -e '2p;4p;12p' file

如果bash命令行太长,

2p;4p;12p内创建一个具有相同结构的临时文件,并使用-f选项

sed -n -f TemporaryFile file