レコードリストから特定の行番号を効率的に選択するには?

レコードリストから特定の行番号を効率的に選択するには?

数字を表すリストが欲しい行番号ソースファイルの対応する行をフィルタリングしてフィルタリングしたいと思います。ソースファイルからこれらの行を抽出するためにUnixパイプラインをどのように構築できますか?

パイプラインは次のとおりです。

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

これを行うためにUNIXツールの組み合わせをすぐに考えることはできません。代替方法は、sed -n [number]p sourcefile.tsvlinenumbers.txtのすべての数値に対してこれを行うbashスクリプトを作成することです。

私のバックアッププランが他のオプションと比較して合理的にうまく機能している場合は、その内容も教えてください。

答え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を使って正しい道を進んでいます。あなたがしなければならないのは、行番号のリストとp改行文字を変換し、それを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

関連情報