約1500万行の大きなファイルがあります。奇数行にはキー(キーだけでなく)も含まれ、行もデータです。つまり、ファイルは次のようになります。
WRTZ Tyrosine
1287998798
ASDF Proline
9408654860
TYSR Serine
9809804090
ASDF Cytosine
4950409808
ここでキーはASDF
、、、TYSR
ですWRTZ
。
約100,000のキーリストがあります。このキーに対応するデータ(2行)を抽出したいと思います。
私が試した1つの方法は、grep
キーを含む行から行番号を取得し、ループ内でおよびを使用してそのhead
行と次の行を抽出することでした。tail
ただし、実行するのに時間がかかりそうです。
これを行うより効率的な方法はありますか?
答え1
偶数行と奇数行に変化がない場合。次に、次のコマンドを試してください。
awk 'NR%2{printf $1"-";next;}1' <Filename>
上記のコマンドの出力は次のようになります。
WRTZ-1287998798
ASDF-9408654860
TYSR-9809804090
ASDF-4950409808
答え2
小さなawkスクリプトで操作を実行できます。 awk manのマニュアルを読むとわかりやすいです。
#!/usr/bin/awk -f
BEGIN{got=0;linenum=0}
/ASDF/{printf ("%s ",$1); got=1;linenum=NR+1}
/TYSR/{printf ("%s ",$1); got=1;linenum=NR+1}
/WRTZ/{printf ("%s ",$1); got=1;linenum=NR+1}
/^[0-9]/{if ( ( got == 1 ) && ( linenum == NR) ) {
printf("%s\n",$1)
got=0
linenum=0
}}
出力は次のとおりです。
./awk_script data_file
WRTZ 1287998798
ASDF 9408654860
TYSR 9809804090
ASDF 4950409808
自分のニーズに合わせて修正できます!
答え3
grep
最も望むのは、一致の周りに+/-線を表示するためのデフォルトオプションを利用することです。
Context Line Control
-A NUM, --after-context=NUM
Print NUM lines of trailing context after matching lines. Places a line containing a group separator (--) between contiguous
groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.
-B NUM, --before-context=NUM
Print NUM lines of leading context before matching lines. Places a line containing a group separator (--) between contiguous
groups of matches. With the -o or --only-matching option, this has no effect and a warning is given.
-C NUM, -NUM, --context=NUM
Print NUM lines of output context. Places a line containing a group separator (--) between contiguous groups of matches. With
the -o or --only-matching option, this has no effect and a warning is given.
答え4
使用幸せ(以前のPerl_6)
ペアの行を探している場合は、次の手順を実行しrotor
ますbatch
。
~$ raku -e '.put for lines.rotor(2, partial => True).map: *.words[0,2];' file
#OR
~$ raku -e '.put for lines.batch(2).map: *.words[0,2];' file
Rakuのrotor
/batch
ルーチンは、ユーザーが定義した数(例:2
3、4など)の要素(例lines
:)を取得してグループ化できます。完全なペアが必要な場合(つまり、ファイルに偶数行が含まれている場合)、rotor
このpartial => True
パラメータを単に使用して削除するだけです。
注:このコードは、スペースで区切られた基準に従って.words
要素を保持します。たとえば、一部のペアのwords
最初の行に2つがあり、他のペアの最初の行に3つ(またはそれ以上)がある場合、words
問題が発生する可能性があります。
最初を選択すると、word
この問題を回避できます。各行は次のとおりです。
~$ raku -e '.put for lines.rotor(2).map( *.map: *.words[0]);' file
#OR (using `>>` hyper notation):
~$ raku -e '.put for lines.rotor(2)>>.map: *.words[0];' file
入力例:
WRTZ Tyrosine
1287998798
ASDF Proline
9408654860
TYSR Serine
9809804090
ASDF Cytosine
4950409808
出力例(すべてのコード例):
WRTZ 1287998798
ASDF 9408654860
TYSR 9809804090
ASDF 4950409808