2

ログファイルがあります.log:

toto string1 tata string2 tito string3
tata tati string3
titi string1 tato string2 tati toto
.....
tutu string1 tita string2 tita string3

ファイルのすべての行から string1、string2、および string3 を抽出する必要があります。行には、1 つ、2 つ、または 3 つの文字列を含めることができます。

私の最初の試み while read LINE do grep:

while read line; do 
z_string1=`echo $line | egrep 'string1' | cut -f2 xxx | cut -f1 xxxx`
z_string2=`echo $line | egrep 'string2' | cut -f2 xxx | cut -f1 xxxx`
z_string3=`echo $line | egrep 'string3' | cut -f2 xxx | cut -f1 xxxx`
echo "$z_string1,$z_string2,$z_string3" >> results.csv
done < file.log

これは期待どおりに機能しますが、まったく最適化されておらず、非常に遅いです。

ご協力ありがとうございました!

4

4 に答える 4

1

trygrep -oE "string[0-9]" file.log >> results.csv -oフラグは、一致する部分のみを出力として提供します

于 2013-04-26T07:06:24.840 に答える
0

私が見ることができるものから、あなたの文字列パターンは列を変えています:

toto string1 tata string2 tito **string3**
tata tati string3
titi string1 tato string2 tati toto
.....
tutu string1 tita string2 tita string3

2 行目は 3 列目で、残りは column2 であるため、次のように、出力の列番号に依存しても意味がありません。

awk -v pattern="string" '{cols=NF; if ( (cols == 6 ) && ($2 ~ pattern))   { print $2 " " $4 " " $6 } }' test.txt 
string1 string2 string3
string1 string2 toto
string1 string2 string3

それで..

これまたはこれの一部をソリューションに使用できます

    awk -v p1="string1" -v p2="string2" -v p3="string3" 'BEGIN { c1=0; c2=0; c3=0; }
 {if (( $0 ~ p1) || ( $0 ~ p2) || ($0 ~ p3 ))  { 
    for (i=1;i<=NF;i++) {
        if ( $i ~ p1)   { print $i; c1++; 
        } else if  ( $i ~ p2)   { print $i; c2++; 
        } else if ( $i ~ p3)   { print $i; c3++; }
   }  } 
   } END{ print p1"_count:" c1 " "p2"_count:" c2"  "p3"_count:"c3}  ' test.txt

これにより、次が生成されます。

string1
string2
string3
string3
string1
string2
string1
string2
string3
string1_count:3 string2_count:3  string3_count:3
于 2013-04-26T09:28:43.563 に答える
0

bash正規表現マッチングを使用して文字列をキャプチャし (存在する場合)、それらを出力します。あなたの例から、一致が見つからない場合は空の文字列を出力したいだけだと思う​​ので、その動作を維持します。

while read line; do
    [[ $line =~ (string1) ]]; printf "%s," "$BASH_REMATCH"
    [[ $line =~ (string2) ]]; printf "%s," "$BASH_REMATCH"
    [[ $line =~ (string3) ]]; printf "%s\n" "$BASH_REMATCH"
done

perlこれはorソリューションほど高速ではないかもしれませんが、awk追加のプロセスを作成する必要がないため、元のソリューションよりも改善されるはずです。すべてが で行われbashます。

于 2013-04-26T14:51:00.203 に答える