file1からパターンを読み取り、file2から繰り返し検索します。

file1からパターンを読み取り、file2から繰り返し検索します。

file1からパターンを読み取り、file2を繰り返し検索して一致する行と3行を印刷してから、file3に印刷したいと思います。

今私はやっています:

cat file1 | while read line; do awk '/$line/ {for(i=1; i<=3; i++) {getline; print}}' file2 > file3 ; done

これを行うより効率的な方法はありますか?私のirlファイルは巨大です(〜30GB)。

ベストアンサー1

各パターンに対してファイルを一度にスキャンできます。特にファイルがキャッシュに収まらないため、ファイルを一度だけ検索する方がはるかに高速です。

あなたのサンプルコードは実際にfile1。単一のファイルにすべての一致が必要な場合は、パターンが「OR」演算子で連結されるのと同じです。

awk '
    BEGIN {
        while (getline <"file1") pattern = pattern "|" $0;
        pattern = substr(pattern, 2);
    }
    match($0, pattern) {for(i=1; i<=3; i++) {getline; print}}
' file2 > file3

また、一致する行を印刷せずに次の3行だけを印刷することに注意してください。次の3行の前に一致する行を印刷するには、ループの前に追加のprint;項目を追加する必要がありますfor

実際、次の3行の前に一致する行を印刷し、grepコマンドがその-Aパラメータをサポートしている場合は、そのパラメータを使用する必要があります。 grepのような特別なプログラムは、awkのような解釈言語よりも速いことがよくあります。追加ボーナスでコマンドははるかに簡単です。

grep -A -E -f file1 file2 >file3

grepが遅い場合は、マルチバイトロケールのGNU grepに欠陥があるためです。時には、ファイルやパターンにマルチバイト文字が含まれていなくても、非常に遅くなることがあります。 ASCII以外の文字と一致させるために文字クラスを使用しない場合(たとえば、[[:alpha:]]すべてのUnicode文字と一致させるために文字クラスを使用しない場合)、シングルバイトロケールでgrepを実行します。

LC_ALL=C grep -A3 -E -f file1 file2 >file3

grepの出力はawkフラグメントとまったく同じではありません。これは、前の行で印刷された行の1つでパターンが見つかった場合は異なる動作をするためです。たとえば、モードがあり、a行が、、、の場合、が印刷され、上記のa1awkフラグメントは、追加の印刷を含むawkフラグメントは、、、、が印刷されます。a2bcdgrep -A3a1a2bca2bcprinta1a2bc

おすすめ記事