패턴과 일치하지 않는 줄에 텍스트 추가

패턴과 일치하지 않는 줄에 텍스트 추가
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에서 이러한 삽입 문을 추출했습니다. 전혀 이렇게 보이지는 않습니다. 몇 가지 사항을 변경했지만 여전히 정체 상태입니다. 이를 실제 삽입 문으로 변환해야 합니다. 모든 삽입 문에 대해 두 번째 줄(INSERT INTO db. VALUES ()) 뒤의 모든 줄 끝에 쉼표를 추가해야 합니다 . table이는 11번째 줄까지 두 줄 뒤에 쉼표를 추가한 다음 INSERT INTO 이후에 다시 시작하고 반복하는 것을 의미합니다.

구글링해서 이것저것 찾아봤는데

sed '/INSERT/{n;n;n;n;n;s/$/,/}' teststring.txt--> 삽입 후 다섯 번째 줄에 쉼표가 추가됩니다. 문제는 여섯 번째 줄을 다시 실행하면

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 다음 두 번째 줄 끝에 쉼표를 추가합니다. 원하는 대로 할 수 있지만 n;각 명령을 10줄씩 증가시켜 명령을 반복적으로 실행해야 하므로 세 번째 줄의 다음 명령은 다음과 같습니다.

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

n;여기에는 세 개가 있는데 첫 번째 명령에는 두 개가 있습니다 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

두 줄의 패턴 공간을 사용하고 INSERT 또는 ); 없이 모든 줄에 쉼표를 추가할 수 있습니다. 패턴 공간에는 2줄이 있으므로 INSERT 및 );

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

관련 정보