パターンと一致しない行にテキストを追加する

パターンと一致しない行にテキストを追加する
INSERT INTO `db`.`table`
VALUES (
 39741633
 49302045
 0
 44
  '{"CustomerName":"S","CustomerMobile":"8","CustomerEmail":"","VersionId":"5","CityId":"2","CampaignId":"1","InquirySourceId":"3","Eagerness":"-1","ApplicationId":"2","BranchId":"3","AssignedDealerId":"2","DMSInqNo":"45"}'
  NULL
  0
  '2021-11-09 19:11:50'
  NULL
  1
  29
  NULL
);
INSERT INTO `db`.`table`
VALUES (
 39741635
 49970365
 0
 30
  '{"CustomerName":"A","CustomerEmail":"[email protected]","CustomerMobile":"9","VersionId":"6","InquirySourceId":"1","Eagerness":"-1","IsCorporate":"z","CampaignId":"8","BranchId":"3","ApplicationId":"1","Location":{"City":{"CityId":"1"},"Area":{"AreaId":"4"}},"CouponCode":null,"CwOfferId":"0","AssignedDealerId":"0","PinCode":""}'
  NULL
  0
  '2021-11-09 19:11:51'
  NULL
  1
  29
  NULL
);

binlogからこれらの挿入文を抽出しました。まったくそう見えません。いくつか変更しましたが、まだ輻輳状態です。これを実際の挿入ステートメントに変換する必要があります。すべての挿入ステートメントについて、2行目(INSERT INTO db. VALUES())の後のすべての行の末尾にカンマを追加する必要があります。tableこれは、11行目までの2行の後にカンマを追加してから、INSERT INTOの後に再起動して繰り返すことを意味します。

Googleでこれを見つけました。

sed '/INSERT/{n;n;n;n;n;s/$/,/}' teststring.txt-->挿入後、5行目にカンマが追加されます。問題は、6行目をもう一度実行すると

sed '/INSERT/{n;n;n;n;n;n;s/$/,/}' teststring.txt、最初のSEDコマンドによって配置された古いコンマを置き換えます。

ファイルの外観は次のとおりです。

INSERT INTO `db`.`table`
VALUES (
 39741633,
 49302045,
 0,
 44,
 '{"CustomerName":"S","CustomerMobile":"8","CustomerEmail":"","VersionId":"5","CityId":"2","CampaignId":"1","InquirySourceId":"3","Eagerness":"-1","ApplicationId":"2","BranchId":"3","AssignedDealerId":"2","DMSInqNo":"45"}',
  NULL,
  0,
  '2021-11-09 19:11:50',
  NULL,
  1,
  29,
  NULL
);
INSERT INTO `db`.`table`
VALUES (
 39741635,
 49970365,
 0,
 30,
  '{"CustomerName":"A","CustomerEmail":"[email protected]","CustomerMobile":"9","VersionId":"6","InquirySourceId":"1","Eagerness":"-1","IsCorporate":"z","CampaignId":"8","BranchId":"3","ApplicationId":"1","Location":{"City":{"CityId":"1"},"Area":{"AreaId":"4"}},"CouponCode":null,"CwOfferId":"0","AssignedDealerId":"0","PinCode":""}',
  NULL,
  0,
  '2021-11-09 19:11:51',
  NULL,
  1,
  29,
  NULL
);

この目標をどのように達成できますか?

答え1

カンマを追加して、特定の文字列を含まないすべての行を一致させることができます。

sed '/.*VALUES.*\|.*INSERT.*\|);$/! s/$/,/' your_file

仕組みは次のとおりです。

  • を含むVALUESまたはINSERT終了するすべての行に一致します);
  • これは、異なる文字列を一緒に連結することによって行われます\|
  • その後、使用します!(したがって、これらの文字列を含まない行だけが実際に一致します)。
  • 次に、この行の後にコンマを追加します。

必要に応じて機能していることを確認したら、代わりに-i交換を追加してください。

sed -i '/.*VALUES.*\|.*INSERT.*\|);$/! s/$/,/' your_file

編集する

@theyが以下のコメントで指摘したように、このコマンドは各INSERTステートメントの最後の行にもカンマを配置します(これが問題かどうかはわかりません)。

INSERT INTO `db`.`table`
VALUES (
 39741633,
  .
  .
  .
  29,
  NULL,  <--- unecessary comma here
);

答え2

sed -i '/INSERT INTO/{n;n;s/$/,/}' teststring.txt 

このオプションを見逃しました-i。この SED コマンドは、INSERT INTO の後の 2 行目の末尾にコンマを追加します。必要に応じて実行できますが、n;各コマンドを10行ずつ増やしてコマンドを繰り返し実行する必要があるため、3行目の次のコマンドは次のようになります。

`sed -i '/INSERT INTO/{n;n;n;s/$/,/}' teststring.txt`.

n;これには3つあり、最初のコマンドには2つありますn;

誰もがこれを行うより良い方法がある場合は感謝します:-)。

答え3

文字列で始まる行が見つかるたびに、VALUES次の行を編集バッファに追加しますsed。バッファが終了するまでこれを繰り返します);。次に、両側に括弧がないすべての改行文字をコンマで置き換えます。

/^VALUES/ {
    # Loop until the buffer ends with ");".
    # The N command reads the next line and appends
    # it to the buffer, with a newline character as delimiter.
    :again
    N
    /);$/ !b again

    # Replace all newlines with commas,
    # but only if the newline is not immediately
    # next to a parenthesis.
    s/\([^(]\)\n\([^)]\)/\1,\2/g
}

これは別のスクリプトとして使用できますsed

sed -f thescript file

...またはコマンドラインから直接:

sed -e '/^VALUES/ {' \
    -e ':again' \
    -e 'N; /);$/ !b again' \
    -e 's/\([^(]\)\n\([^)]\)/\1,\2/g; }' file

問題の文書を考慮すると、構文的に正しいSQLが次のように生成されます。

INSERT INTO `db`.`table`
VALUES (
 39741633, 49302045, 0, 44,  '{"CustomerName":"S","CustomerMobile":"8","CustomerEmail":"","VersionId":"5","CityId":"2","CampaignId":"1","InquirySourceId":"3","Eagerness":"-1","ApplicationId":"2","BranchId":"3","AssignedDealerId":"2","DMSInqNo":"45"}',  NULL,  0,  '2021-11-09 19:11:50',  NULL,  1,  29,  NULL
);
INSERT INTO `db`.`table`
VALUES (
 39741635, 49970365, 0, 30,  '{"CustomerName":"A","CustomerEmail":"[email protected]","CustomerMobile":"9","VersionId":"6","InquirySourceId":"1","Eagerness":"-1","IsCorporate":"z","CampaignId":"8","BranchId":"3","ApplicationId":"1","Location":{"City":{"CityId":"1"},"Area":{"AreaId":"4"}},"CouponCode":null,"CwOfferId":"0","AssignedDealerId":"0","PinCode":""}',  NULL,  0,  '2021-11-09 19:11:51',  NULL,  1,  29,  NULL
);

質問の正確な結果が必要な場合は、最後の交換を次のように置き換えてください。

s/\([^(]\)\(\n\)\([^)]\)/\1,\2\3/g

改行をコンマで置き換える代わりに、各改行の前にコンマを挿入します。

答え4

2行のパターンスペースを使用し、INSERTまたは)。なしで任意の行にカンマを追加できます。パターンスペースには2行があるため、INSERTと)。

sed -e '
  $!N;/INSERT\|);$/!{s/\n/,&/;P;D;}
' file

関連情報