0

私はbashで解決しようとしている次の問題があります。次のような情報のリストを含む2つの異なるファイル(file1、file2)があります。

HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

表示された文字列は、単一の行を表します。私がそうするならそれを意味する:

grep "HWI-1KL104:145:C18ANACXX:5:1101:1168:2164" file1

私の出力は上記の文字列です。HWI- 1KL104 :145:C18ANACXX:5:1101:1168:2164は私の回線のIDを表します

さまざまなIDを持つこのような数百万行(最大8GBのtxtファイル)を想像する必要があります

私がしなければならないことは:

  1. file2に存在するfile1に存在するIDを検索します

  2. file2の一致した行を、IDと次の情報のみを含む新しいファイルに保存します。

HWI-1KL104:145:C18ANACXX:5:1101:1196:2120 CCCCTTCTCCAGGGGACCANGTATGTTTCTCTTATGGTCCTCCTTGTTTACTAGCTTCTCTGGCAGTGAGATTGTAGGCTGGTAATCCTTTACTCNNTNNN CCCFFFFFHHHHHJJJJJJ#4CDEEDCDDDDDC ######

したがって、4 * 0 0 * * 0 0で表されるものを破棄します(これは、長さに関しては固定されていますが、コンテンツでは固定されていません。つまり、3 * 1 0 * * 0 1などになる可能性があります)。

したがって、私のfile1は、見つけてfile2に保存したいIDの一種の「参照」を表しています。

説明するのはとても難しいです。私がやりたいことをご理解いただければ幸いです。

はうまくいくはずだと思いますが、行内のいくつかの情報だけを調べて別のファイルと比較するgrep方法がわかりません。grep

4

4 に答える 4

2

file2 contiansは、必要なキーIDのリストにすぎません。

awk 'NR==FNR{ids[$0];next} $1 in ids{print $1,$10,$11}' file2 file1
于 2013-01-28T16:10:23.460 に答える
1

forループを使用できます

    outputfile="/tmp/something"
    file1=3; file2=4; 
    for ids in $(cat $file1|awk '{print $1}'); 
    do
          #echo working on $id**
          grep $ids $file2|awk '{print $3" "$4" "$5}' >> $outputfile
    done

上記は同じスクリプトが展開され、出力がファイルに送信されるため、スクリプトをファイルにポンプするのではなく、スクリプトを実行して、出力を配置する場所を処理させることができます。

確かに、大きなファイルで実行できます。開始に時間がかかり、終了するまでに時間がかかる場合があります。この方法を使用する場合の問題は、機能し、簡単に使用できることですが、一部のファイルほど高速ではない場合があります。他の複雑な方法が提案されました。

id行での作業を有効にして、より詳細にすることができます

その他の注意事項:

for filesfound in $(pattern=1101; grep $pattern 3*|awk -F":" '{print $1}'); do
 echo "found $filesfound"; 
 grep "newpattern" $filesfound; 
 done;

found 3
found 33

次のように、最初のgrepをさらに掘り下げることができます。

 grep $pattern *|awk -F":" '{print "-- FILE: " $1 " --- ENTIRE_STRING: "$0}'
-- FILE: 3 --- ENTIRE_STRING: 3:HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
-- FILE: 33 --- ENTIRE_STRING: 33:HWI-1KL104:145:C18ANACXX:5:1101:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############

これにより、ファイル名|すべての文字列が返され、パターンが検索され、パターンの後のすべてが返されます。行の最後にawkステートメントを追加することでカスタマイズできます。

pattern=1101; grep $pattern *|awk -F":" '{print $1"|"$0}'|awk -F"$pattern" '{print $2}'
:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
:1168:2164   4   *   0   0   *   *   0   0   GTGCCTGAACTGGATGCATNGACAATGGGGAACATTACATATATAATACAAGGGAAACTCAAACGTTTCCNNNNNCAAGTATTTGACAGNNNNNNNNNNNN   @B@DDFFFHHHHHIHIJIJ#3AFGHHJJJJIIJJIJIIIJJJJJJJGIIJIJJJIJIJJJJIJJI=@EED#####,,5=;ADDFEEDDD############
于 2013-01-28T15:01:21.343 に答える
0

file2のどのフィールドが必要かは明確ではありませんが、開始点としては次のようになります。

grep -Ff file1 file2 | tr -s ' ' | cut -d' ' -f1,9,10

または、file2がタブ区切りの場合:

grep -Ff file1 file2 | cut -f1,9,10

ちなみに、このデータはテキストファイルではなくデータベースに保存する必要があります。

于 2013-01-28T14:22:52.350 に答える
0

4 * 0 0 * * 0 0常に同じ形式ですか?考えられるさまざまなケースを知らずにこれに答える方法を言うのは少し難しいです。IDはどうですか、それは常に同じ形式ですか?

grepを使用して(行全体ではなく)IDのみを取得するには、を使用します-o。これは、行全体ではなく、一致したテキストのみを返します。

新しいファイルへの書き込みと破棄には、文字列の逆をgrepするために4 * 0 0 * * 0 0使用できます。grep -vしたがって、使用しているラインがすでにわかっている場合は、grep -v '4 * 0 0 * * 0 0'

とにかく、これの多くは入力の正確な形式とさまざまなエッジケースに依存しますが、それで始めることができます。

于 2013-01-28T14:23:54.187 に答える