한 줄에서 다음 줄의 특정 위치에 텍스트 표시를 삽입합니다.

한 줄에서 다음 줄의 특정 위치에 텍스트 표시를 삽입합니다.

SQL 문으로 변환해야 하는 텍스트 데이터가 포함된 파일이 있습니다.


@Parse ABC
// This is a comment

//-----

"f2"
f4-1
$f5f5f5f5 0000
f4-2
$f5f5f5f5 0001
$f5f5f5f5 0002
f4-3
$f5f5f5f5 0003
$f5f5f5f5 0004
f4-4
$f5f5f5f5 0005
$f5f5f5f5 0006
f4-5
$f5f5f5f5 0007
$f5f5f5f5 0008
$f5f5f5f5 0009
$f5f5f5f5 0010
$f5f5f5f5 0011
$f5f5f5f5 0012

//========

"This is f2 but is different from the previous f2"
f4-6
$f5f5f5f5 0013
f4-7
$f5f5f5f5 0014
$f5f5f5f5 0015
f4-8
$f5f5f5f5 0016
$f5f5f5f5 0017
f4-9
$f5f5f5f5 0018
$f5f5f5f5 0019
f4-10
$f5f5f5f5 0020
$f5f5f5f5 0021
$f5f5f5f5 0022
$f5f5f5f5 0023
$f5f5f5f5 0024
$f5f5f5f5 0025

//========


처음에는 파일이 위와 같습니다.

파일이 다음과 같기를 원합니다

INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "f2-1", "", "f4-1", "$f5f5f5f5 0000");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "f2-1", "", "f4-2", "$f5f5f5f5 0001<TAB>$f5f5f5f5 0002");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "f2-1", "", "f4-3", "$f5f5f5f5 0003<TAB>$f5f5f5f5 0004");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "f2-1", "", "f4-4", "$f5f5f5f5 0005<TAB>$f5f5f5f5 0006");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "f2-1", "", "f4-5", "$f5f5f5f5 0007<TAB>$f5f5f5f5 0008<TAB>$f5f5f5f5 0009<TAB>$f5f5f5f5 0010<TAB>$f5f5f5f5 0011<TAB>$f5f5f5f5 0012");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "This is f2-2 but is different from the previous f2-1", "", "f4-6", "$f5f5f5f5 0013");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "This is f2-2 but is different from the previous f2-1", "", "f4-7", "$f5f5f5f5 0014<TAB>$f5f5f5f5 0015");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "This is f2-2 but is different from the previous f2-1", "", "f4-8", "$f5f5f5f5 0016<TAB>$f5f5f5f5 0017");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "This is f2-2 but is different from the previous f2-1", "", "f4-9", "$f5f5f5f5 0018<TAB>$f5f5f5f5 0019");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "This is f2-2 but is different from the previous f2-1", "", "f4-10", "$f5f5f5f5 0020<TAB>$f5f5f5f5 0021<TAB>$f5f5f5f5 0022<TAB>$f5f5f5f5 0023<TAB>$f5f5f5f5 0024<TAB>$f5f5f5f5 0025");

아래 명령을 사용하여 원본 파일을 현재 출력으로 변경했습니다. 아래 명령에 사용된 모든 파일에는 dos 줄 끝이 있습니다.

sed -e 's/[[:space:]]$//' -e 's/^[[:alnum:]*()].*/INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "&", "");/' /path/to/files/* > '/path/to/file.sql';

"file.sql"의 현재 데이터는 다음과 같습니다.


@Parse ABC
// This is a comment

//-----

"f2"
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-1", "");
$f5f5f5f5 0000
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-2", "");
$f5f5f5f5 0001
$f5f5f5f5 0002
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-3", "");
$f5f5f5f5 0003
$f5f5f5f5 0004
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-4", "");
$f5f5f5f5 0005
$f5f5f5f5 0006
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-5", "");
$f5f5f5f5 0007
$f5f5f5f5 0008
$f5f5f5f5 0009
$f5f5f5f5 0010
$f5f5f5f5 0011
$f5f5f5f5 0012

//========

"This is f2 but is different from the previous f2"
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-6", "");
$f5f5f5f5 0013
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-7", "");
$f5f5f5f5 0014
$f5f5f5f5 0015
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-8", "");
$f5f5f5f5 0016
$f5f5f5f5 0017
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-9", "");
$f5f5f5f5 0018
$f5f5f5f5 0019
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-10", "");
$f5f5f5f5 0020
$f5f5f5f5 0021
$f5f5f5f5 0022
$f5f5f5f5 0023
$f5f5f5f5 0024
$f5f5f5f5 0025

//========


위의 데이터를 다음과 같이 변경하고 싶습니다.

INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-1", "");
INSERT INTO `` (`f1`, `f2`, `f3`, `f4`, `f5`) VALUES (NULL, "", "", "f4-2", "$f5f5f5f5 0000");

데이터가 포함된 파일에는 dos 줄 끝이 있습니다.

sed -r "s/\", \"\"\);\r\n(.*)\r\nINSERT INTO/\", \"\1\");\r\nINSERT INTO/" /path/to/file.sql;

위 명령은 오류 없이 실행되지만 명령 출력은 입력과 동일합니다.

처음에는 제대로 작동하도록 노력했지만 이로 인해 대부분 고정된 문자 문제를 sed -e피하는 수정 불가능한 오류가 발생했습니다 .sed -r

방금 .\r\n----하지만 교체되지 않았기 때문에 여기에 문제가 있다고 생각합니다.

그래서 나는 sed온라인 작업을 발견했지만 그것을 깨닫지 못했습니다. 따라서 반드시 sed에서 수행할 필요는 없습니다. 대신에 무엇을 사용할지는 모르겠지만 누군가가 제안하고 싶다면 기꺼이 할 것입니다. 문제가 발생하면 직접 시도해 보세요. 문제를 발견하면 다시 게시할 수 있습니다.

답변1

노트이 답변이 게시된 이후 예제 입력/필수 출력이 크게 변경되었으므로 현재 문제가 해결되지 않을 수 있습니다.

다음 솔루션은 다음을 가정합니다.

  • 삽입할 값은 행의 유일한 문자열 토큰입니다.
  • 값이 삽입되는 곳은 "");스키마 입니다.

이 경우 다음 awk절차가 작동해야 합니다.

awk 'index($0,"INSERT")==1 && buf {sub(/"");/, "\"" buf "\");"); buf=""}
NF==1{buf=$1;next} 1' input.txt

작동 방식은 다음과 같습니다.

  • 행이 로 시작하고 버퍼 변수가 채워지면 INSERT패턴은 , , 마지막으로 대체됩니다. 그런 다음 변수가 지워집니다.buf"");"buf");buf
  • 행에 필드가 하나만 있는 경우 이 행은 다음 행에 채워질 값이 포함된 행으로 간주되어 변수에 입력됩니다 buf(그렇지 않으면 처리가 즉시 다음 행으로 이동합니다).
  • 1규칙 블록 외부에 있는 것으로 보이는 것은 모든 수정 사항을 포함하여 현재 줄을 인쇄하도록 { ... }지시합니다 .awk

행 앞에 여러 "값" 행이 있는 경우 INSERT마지막 "값" 행의 내용을 사용합니다. 빈 줄은 무시됩니다(그러나 출력에는 계속 나타납니다). 로 시작하지 않는 여러 "단어"가 포함된 줄 INSERT도 그대로 인쇄됩니다.

awk파일의 내부 편집은 기본적으로 수행되지 않으므로( 에서와 같이 ) sed출력을 파일로 리디렉션하고 나중에 원래 입력을 덮어써야 합니다. 또는 (상당히 새로운 GNU Awk가 있는 경우) -i inplace확장을 사용하십시오. 내부 편집을 수행합니다.

dos2unixDOS 줄 끝을 Unix 스타일로 바꾸려면 처리하기 전에 원본 파일을 실행하는 것이 좋습니다 . unix2dos수정된 파일에 DOS 줄 끝이 필요한 경우 나중에 실행할 수 있습니다.

답변2

행 쌍을 처리하려면 sed다음 N;P;D패턴을 사용할 수 있습니다. N버퍼에 추가 행을 추가하고 P버퍼의 첫 번째 행만 인쇄한 다음 D첫 번째 행을 삭제하여 두 번째 행이 아직 버퍼에 있는 동안 스크립트를 계속 실행합니다.

귀하의 경우에는 다음과 같은 결과가 발생합니다.

sed 'N;s/", "");\r\n\($[^ ]*\).*/", "\1");/;P;D' /path/to/file

이제 추가 행이 있는 경우 무엇을 하고 싶은지 잘 모르겠습니다. 아마도 그냥 제거해 보세요:

sed '/^$/d;N;s/", "");\r\n\($[^ ]*\).*/", "\1");/;P;D' /path/to/file

관련 정보