
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
확장을 사용하십시오. 내부 편집을 수행합니다.
dos2unix
DOS 줄 끝을 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