我想从大文件中选择大量特定行。
使用perl,我正在创建一个这种样式的命令(这里打印第2行和第4行):
sed -n -e 2p -e 4p $file
使用system()命令启动它。
这种方法很好,除非从文件中选择的行数变得非常大。它目前可以使用大约10,000行,但不能用于我想要选择~17,000行的另一个文件。可以传递给sed的参数数量是否有限制?是否有可供使用的替代UNIX工具? 谢谢你的帮助
答案 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
这将打印行2
,8
和12
将行2
打印到7
和12
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