行と列の多い区切りファイル()がある場合data.txt
:
346 dfd asw 34
565 sd wdew 34
667 ffg wew 23
473 sa as 21
533 jhf qwe 54
抽出したい行番号を含む他のファイル(positions.txt
)
3
5
8
positions.txt
このファイルを使用してその場所を抽出するにはどうすればよいですかdata.txt
?以下は私が期待する結果の例です。
667 ffg wew 23
533 jhf qwe 54
答え1
簡単にawk
:
awk 'NR==FNR{ pos[$1]; next }FNR in pos' positions.txt data.txt
NR==FNR{ ... }
- 最初の入力ファイル(例positions.txt
:)を処理します。pos[$1]
- 累積位置(レコード数)を配列キーにpos
設定next
- 次のレコードに移動
FNR in pos
- 2番目の入力ファイルを処理するときdata.txt
(FNR
現在の入力ファイルから読み取られたレコード数を示す)、現在のレコード番号が位置FNR
配列にある場合にのみレコードを印刷するpos
(キーで検索)
出力例:
667 ffg wew 23
533 jhf qwe 54
...
答え2
まず、ファイルsed
からスクリプトを作成します。positions.txt
sed 's/$/p/' positions.txt
これは出力されます
3p
5p
8p
この単純なスクリプトは、指定された行だけを印刷します。
data.txt
次にファイルに適用します。使用している場合bash
(またはプロセス置換を理解するシェル<( ... )
):
sed -n -f <( sed 's/$/p/' positions.txt ) data.txt
指定されたスクリプトによって明示的に印刷された内容を除く-n
すべての出力を停止します。sed
sed
与えられた例に基づいて、これは次のようになります。
667 ffg wew 23
533 jhf qwe 54
使用しないbash
場合
sed 's/$/p/' positions.txt >filter.sed
sed -n -f filter.sed data.txt
rm -f filter.sed
…同じことをします。
答え3
ソートされている場合は、ストレージ全体をpositions.txt
使用せずに2つのファイルを同時に渡すことでこれを行うこともできます。以前に一致した行が満たされている場合は、次の行をお読みください。positions.txt
positions.txt
$ awk -vpos=positions.txt 'function get() { getline num < pos }
BEGIN { get() } NR==num { print; get() }' data.txt
667 ffg wew 23
533 jhf qwe 54
実際、これは両方のファイルが非常に大きい場合にのみ機能します。本物十分な保存。
答え4
単純なforループでこれを行うことができます。
方法 1 は sed と for ループを使用します。
for i in `cat positions.txt`; do sed -n ""$i"p" data.txt ; done
出力
667 ffg wew 23
533 jhf qwe 54
方法 2 は awk と for ループを使用します。
for i in `cat positions.txt`; do awk -v i="$i" 'NR==i {print $0}' data.txt ;done
出力
667 ffg wew 23
533 jhf qwe 54