BashでSQLファイルをチャンクで読み込む

BashでSQLファイルをチャンクで読み込む

私はBashで文字列置換型の操作を実行しようとしてきました。しかし、見るほど簡単ではありません。これの説明は次のとおりです。

複数のSQLファイルが含まれているとします。選ぶそこにある声明。各選ぶブロックはセミコロン(;)。

私の目標は、各チャンクを個別に保持し、いくつかのタスクを実行することです。ただし、スクリプトは異なるSQLファイルを使用して各ブロックを変数に格納するため、これらのブロックを動的に識別できる必要があります(例:1)後でブロックを簡単に使用できるようにします。

PS私は先週この問題で苦労しました。アドバイスをいただきありがとうございます。また、以下では、これまでに使用したいくつかの正規表現型項目を表示できます。

egrep -e "^(\s|SELECT).*.[^;]\s*" test.sql

この

cat test.sql | awk '" "{found=0} /SELECT/{found=1} {if (found) print }'

最初の方法が最もうまく機能し、目標に最も近いですが、SELECTステートメントブロックを分離して保存する方法が見つかりませんでした。 2番目は、同様の表現を使用してセミコロンを探します。それ以外は、2つの項目の間にあるすべての項目を3番目の項目として使用するようにスクリプトに指示し、3つの項目をまとめて保存してみました。しかし、正しく動作しませんでした。 SELECT 文は複数行です。

答え1

「newline」以外の区切り文字を使用して読み取りループを使用できます。これにより、readコマンドはbash区切り文字で終わると複数行を1つとして扱います。

注:この方法は、ファイルのコメントまたは文字列にセミコロンが表示される場合は適していません。これはパーサーではありません。単なる読み込みループです。

while read -rd ';' sql
do
    if [ "${sql#SELECT}" = "$sql" ]
    then
        echo "Not a SELECT!"
    else
        echo "This is the command I got:"
        echo ">>$sql<<"
    fi
done < test.txt 

read -rd ';' sqlセミコロンが表示されるまで入力を読みます。ブロックは変数に配置されます$sql

ifループ内で変数のテキストの先頭から単語を削除すると、変更されることをSELECT確認します。基本的には、テキストが単語で始まらないかどうかを尋ねることですSELECT

read「単語」を見つけると、各ブロックの最初の文字と末尾のスペースが削除されます。したがって、セミコロンの前後の空行は削除されます。

テキストファイルの例:

   SELECT *
FROM PLANTS

WHERE TYPE='BUSH'

;

INSERT INTO PLANTS (TYPE,NAME,ID)
VALUES ('TREE', 'Oak', 15)    ;   

SELECT NAME
FROM PLANTS
WHERE NAME LIKE 'O%';

次の出力が生成されます。

This is the command I got:
>>SELECT *
FROM PLANTS

WHERE TYPE='BUSH'<<
Not a SELECT!
This is the command I got:
>>SELECT NAME
FROM PLANTS
WHERE NAME LIKE 'O%'<<

答え2

awk -v RS=";" '/SELECT/{print $0";"}'

レコード(is RS;に文字列がある場合は、SELECT最後に一緒に印刷されます。;

関連情報