1

選択した出力を切り取ろうとしている 10GB の CSV ファイルがあります。現時点では次のものがありますが、サイズが大きいためにリソースを消費しすぎているため、最適化を検討しています。

#!/bin/bash
FILE=data.txt
FILEPATH=/home/user/

if [[ -z $1 ]]; then
        echo "No search parameter specified. Specify one when running this."
fi

echo "Searching $FILEPATH/$FILE for $1.. this may take a while."
echo ""

while IFS= read -r LINE;
        do
                # Grep for $1 and cut select columns
                grep $1 | cut -d"," -f7,9,15,16,19,22,23,24
        done

入力ファイルのサンプル行は次のようになります。

結果: キー=値1、エラー=0、コマンド=SetOperator|ソース: ファイル=/home/user/logs/current、start_date=20130128、

私がやりたいことは、ファイルで任意の値を検索し、結果が見つかったすべての行から (カットされたバージョンの) 結果を返すようにすることです。
たとえば、「20130128」を検索すると、次のように返されます。

SetOperator,value1,20130128,

つまり、コマンドと等号の両方を区切り文字として処理する必要があります。

私は SO (つまり、this ) を調べて、いくつかの Google-fu を費やしましたが、「読み取り」は遅く、これらのような大きなファイルには最適化されていないことが一般的に認められています。私は多くの選択肢を見つけていません。

何を使用することをお勧めしますか?
ありがとう!

4

2 に答える 2

1

書かれたコマンド:

while IFS= read -r LINE;
        do
                # Grep for $1 and cut select columns
                grep $1 | cut -d"," -f7,9,15,16,19,22,23,24
        done

ファイルでもパイプでもgrepを実行していないため、終了することはありません。

grep とパイプとカットを使用したループの代わりに、これを試してください。

awk -v re="$1" 'BEGIN{FS=OFS=","} $0~re{print $7,$9,$15,$16,$19,$22,$23,$24}' "${FILEPATH}/${FILE}"
于 2013-01-29T14:33:23.847 に答える
0

テストする 10GB のファイルはありませんが、grep の man ページには、役立つ可能性のある 2 つのオプションが示されています。

--line-buffered
出力で行バッファリングを使用します。これにより、パフォーマンスが低下する可能性があります。

--mmap
可能であれば、デフォルトの read(2) システムコールの代わりに mmap(2) システムコールを使用して入力を読み取ります。場合によっては、 --mmap を使用するとパフォーマンスが向上します。ただし、grep の動作中に入力ファイルが縮小したり、I/O エラーが発生した場合、 --mmap は未定義の動作 (コア ダンプを含む) を引き起こす可能性があります。

ラインバッファリングオプションを使用すると、コマンド全体の実行が遅くなりますが、結果の取得が速くなり、mmap が奇妙になる可能性があります。

これらのオプションを使用すると、以下のようにループが不要になります。

grep --mmap "pattern" file | cut -d"," -f7,9,15,16,19,22,23,24

また

grep --line-buffered "pattern" file | cut -d"," -f7,9,15,16,19,22,23,24
于 2013-01-29T13:25:09.117 に答える