如何有效地从记录列表中选择特定行号?

如何有效地从记录列表中选择特定行号?

我想要一个代表数字的列表行号源文件的我想过滤并过滤源文件中的那些行。我如何构建一个unix管道来从源文件中提取这些行?

管道可能如下所示:

cat sourcefile.tsv | some-filter linenumbers.txt  > extractedrecords.tsv

我无法立即想到 UNIX 工具的组合来完成此任务。后备方法是编写一个 bash 脚本,sed -n [number]p sourcefile.tsv对 linenumbers.txt 中的每个数字执行此操作。

如果我的后备计划与其他方案相比相当有效,请也​​让我知道。

答案1

假设linenumbers.txt每行有一个数字

awk 'NR == FNR{a[$0]; next};FNR in a' linenumbers.txt sourcefile.csv > extractedrecords.tsv

可能会完成这项工作。

或者,与bash

join  -t':' -o2.1,2.2  <(sort linenumbers.txt) <(awk '{print NR":"$0}' \
sourcefile.csv | sort -k1,1 -t':')  | sort -k1,1n -t':' | cut -f2- -d':'

需要所有额外的跳跃,因为join不支持按数字排序的输入文件

答案2

您使用 sed 的方向是正确的:您需要做的就是将行号列表转换为后跟 ap和换行符,并将其用作 sed 脚本。例如,如果您有一个以空格分隔的列表:

lines="2 3 5 7 11 13"
<sourcefile.tsv sed -n "$(echo "$lines" | sed 's/$/p/; s/ /p\n/')"  >extractedrecords.tsv

awk 是另一种可能性。

lines="2 3 5 7 11 13"
export lines
<sourcefile.tsv awk '" "ENVIRON["lines"]" " ~ " "NR" "' >extractedrecords.tsv

相关内容