2017-04-17 15 views
1

私は、タグの各ブロックは、オブジェクトを移入するために必要なデータを表し、このスピードアップこのbashスクリプト

<Tag1>content 
<Tag2>optional tag content 
<Tag3>content 

<Tag1>other content 
<Tag3>other content 

のような形式のデータを含むファイルを持っています。一部のタグもオプションです。

現在、私はこのコードタグとtrは、データを以下のいずれかの新しい行を削除した後、カットデータを取得

#!/bin/bash 
tag1="" 
tag2="" 
tag3="" 

while read line; do 

if [[ $line == '<Tag1>'* ]] 
    then 
    tag1=`echo $line | cut -c 6- | tr -d '\r'` 
elif [[ $line == '<Tag2>'* ]] 
    then 
    tag2=`echo $line | cut -c 6- | tr -d '\r'` 
elif [[ $line == '<Tag3>'* ]] 
    then 
    tag3=`echo $line | cut -c 6- | tr -d '\r'` 
    #write new object to output file and reset tag variables 
fi 

done <file.dat 

とデータファイルを処理しています。

このコードは非常に遅いですが、何千ものファイルを処理する場合は特にそうです。

これを行うための高速な方法がありますか、オプションのタグを処理する方法はありますか? "

EDIT:

イムので、私は、INSERT文を作成するために、出力を使用して、SQLテーブルを移入するためにそれを使用して:

echo "INSERT INTO MyTable VALUES('$tag1','$tag2','$tag3');" >> output.sql 

第二編集

<Tag1>Some sample text including don't 
<Tag2>http://google.com 
<Tag3>$100 
の入力を考えます

理想的な出力は、INSERT INTO MyTable Values(「いくつかのサンプルテキストには、 、 "http://google.com"、 "$ 100");

単引用符を使用して値を渡して引用符を使用しない場合は、「入力しない」のようにアポストロフィを2倍しなければならないことは明らかです。あなたが期待される出力を示していないので、

+1

はい、awkで書き直すと、少なくとも1桁以上速くなります。[なぜシェルをループ処理するのかを理解するために(https:///unix.stackexchange.com/questions/169716/why-is-using-a-shell-loop-to-process-text-considered-bad-practice)。あなたの質問は、私たちがあなたを助けることができるように入力を与えられた期待される出力を表示する。 –

+0

@Ed出力を含めるように編集しました – najd1103

+0

@EdMortonごめんなさい最新の編集がうまくいけばあなたの質問に答えてくださいね – najd1103

答えて

3

は、それはあなたの質問から明らかではないのですが、これはあなたが探しているものかもしれません:ここでは、テストするために私たちを尋ねるべきである入力ファイルのようなものだ

$ cat tst.awk 
BEGIN { 
    RS = "" 
    FS = "\n" 
    fmt = "INSERT INTO MyTable VALUES(\047%s\047, \047%s\047, \047%s\047);\n" 
} 
{ 
    delete v 
    for (i=1;i<=NF;i++) { 
     tag = val = $i 
     gsub(/^<|>.*/,"",tag) 
     sub(/^[^>]+>/,"",val) 
     v[tag] = val 
    } 
    printf fmt, v["Tag1"], v["Tag2"], v["Tag3"] 
} 

$ cat file 
<Tag1>with 'single\' quotes 
<Tag2>http://foo.com 
<Tag3>trailing backslash\ 

<Tag1>With <some> "double\" quotes 
<Tag3>with \1 backrefs & here 

、ここで上記のスクリプトが生成する出力は、その入力を与えています:

を、それはいくつかの伝統的な問題の文字と文字列が含まれているようで

もしあなたが望んでいないものがあれば、その入力(または同様のもの)とあなたが望む出力を表示するために質問を編集してください。

3

awkソリューションは、おそらく速いだろうが、このバッシュ・ソリューションは、元のコードよりも速くする必要があります:

#!/bin/bash 
regex="^<Tag([1-3])>(.*)$" 
while IFS= read -r line 
do 
if 
    [[ $line =~ $regex ]] 
then 
    case ${BASH_REMATCH[1]} in 
    1) tag1=${BASH_REMATCH[2]} ;; 
    2) tag2=${BASH_REMATCH[2]} ;; 
    3) echo "INSERT INTO MyTable VALUES('$tag1','$tag2','${BASH_REMATCH[2]}');" >> output.sql 
     tag1= ; tag2= ;; 
    esac 
fi 
done <file.dat 

、すべての行が同じ正規表現と一致していることに注意してください1/2/3 case文によって処理されます。明らかに、上記はタグや大文字/小文字の空白に非常に敏感なので、実際のデータを考慮し、バリエーションを許容するために必要な場合は正規表現に必要な調整を加えてください。