【发布时间】:2011-01-02 06:54:41
【问题描述】:
使用 sed 或类似工具如何从文件中提取行?如果我想要文件中的第 1、5、1010、20503 行,我将如何获得这 4 行?
如果我需要提取大量行怎么办? 如果我有一个包含 100 行的文件,每行代表一个我想从另一个文件中提取的行号,我该怎么做?
【问题讨论】:
标签: unix sed awk line-numbers text-extraction
使用 sed 或类似工具如何从文件中提取行?如果我想要文件中的第 1、5、1010、20503 行,我将如何获得这 4 行?
如果我需要提取大量行怎么办? 如果我有一个包含 100 行的文件,每行代表一个我想从另一个文件中提取的行号,我该怎么做?
【问题讨论】:
标签: unix sed awk line-numbers text-extraction
类似“sed -n '1p;5p;1010p;20503p'。执行命令“man sed”了解详情。
对于您的第二个问题,我会将输入文件转换为一堆 sed(1) 命令来打印我想要的行。
【讨论】:
sed -f
sed -n '1p;5p;1010p;20503p inputFile.txt > outputFile.txt
使用 awk 很简单:
awk 'NR==1 || NR==5 || NR==1010' "file"
【讨论】:
@OP,您可以使用 awk 更轻松、更高效地完成此操作。所以对于你的第一个问题
awk 'NR~/^(1|2|5|1010)$/{print}' file
第二个问题
awk 'FNR==NR{a[$1];next}(FNR in a){print}' file_with_linenr file
【讨论】:
FNR==NR 只会在读取file_with_linenr 时出现,而不是file。在这种情况下,该行的文本被添加到集合a,并且执行跳到下一行输入。因此,从file 读取时,仅适用(FNR in a) 情况,如果在解析file_with_linenr 时将其编号放入a,则打印相关行的文本。
这并不漂亮,在某些情况下它可能会超出命令长度限制*:
sed -n "$(while read a; do echo "${a}p;"; done < line_num_file)" data_file
或者它更慢但更有吸引力,并且可能更乖巧的兄弟姐妹:
while read a; do echo "${a}p;"; done < line_num_file | xargs -I{} sed -n \{\} data_file
变体:
xargs -a line_num_file -I{} sed -n \{\}p\; data_file
您可以通过添加带有一些大参数的 -P 选项来稍微加快 xarg 版本,例如 83 或 419 甚至 1177,但 10 似乎和任何一个一样好。
*xargs --show-limits </dev/null 可以有指导意义
【讨论】:
我会研究 Perl,因为它具有 sed 的正则表达式工具以及围绕它的编程模型,允许您逐行读取文件,计算行数并根据您想要的内容进行提取(包括从行号文件)。
my $row = 1
while (<STDIN>) {
# capture the line in $_ and check $row against a suitable list.
$row++;
}
【讨论】:
$.,它会自动包含当前行号
在 Perl 中:
perl -ne 'print if $. =~ m/^(1|5|1010|20503)$/' file
【讨论】: