sed(또는 awk): n번째 줄마다 "commit;" 새 줄을 추가합니다. 단, 다음 줄이 패턴으로 시작하는 경우에만 해당됩니다.

sed(또는 awk): n번째 줄마다 "commit;" 새 줄을 추가합니다. 단, 다음 줄이 패턴으로 시작하는 경우에만 해당됩니다.

매우 큰 SQL 파일이 있는데 예를 들어 100000줄마다 "commit;"이라는 새 줄을 추가하고 싶습니다.

이것은 쉽지만 SQL에는 개행 문자가 있는 CLOB 및 BLOB가 포함되어 있습니다.

이 행 내에 새 행이 생성되지 않았는지 확인해야 합니다.

즉, 매 n번째 줄마다 "커밋"을 해야 하지만, 다음 줄이 "INSERT INTO"로 시작하는 경우에만 가능합니다.

입력하다:

INSERT INTO X ..... );
INSERT INTO X ..... );
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
INSERT INTO X ..... );

예상 출력(이 예에서는 두 번째 행마다 커밋이 추가된다고 가정):

INSERT INTO X ..... );
INSERT INTO X ..... );
commit;
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
commit;
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
commit;
INSERT INTO xxx ..... );

조언해주셔서 정말 감사드립니다 :)

답변1

commit아래는 세 번째 삽입마다 붙여넣는 예입니다.

sed '0~2{:a;N;/;$/!ba;s/$/\ncommit;/}'

각 삽입은 줄 끝으로 끝난다고 가정합니다 ;. (줄 끝에 공백이 있는 줄이 있으면 \s*그 뒤에 추가해야 할 수도 있습니다.;

논리는 3개의 행을 잡고 ;끝에 하나가 있는지 확인한 다음 ;끝에 행을 얻을 때까지 더 많은 행을 연결하는 것입니다. 그런 다음 commit;.

해당 행을 추가한 후 다음 행을 계속 처리합니다.

필요에 따라 행 수를 자유롭게 조정하세요.

답변2

솔루션은 awk각 행 세트 n( n = 3예제에서는)를 가져와서 "INSERT INTO"로 시작하는 경우 마지막 행 앞에 "COMMIT"를 삽입합니다.

$ awk '{ if (/^INSERT INTO/ && NR%3 == 0) { print "commit;" }; print }' input

답변3

모든 UNIX 시스템의 모든 쉘에 있는 awk의 경우 모든 INSERT 문의 끝에 있을 때 게시한 입력 예에서와 같이 줄 끝에 세미콜론만 있다고 가정합니다.

$ awk '{print} /;$/ && !((++c)%2){print "commit;"}' file
INSERT INTO X ..... );
INSERT INTO X ..... );
commit;
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
commit;
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
commit;
INSERT INTO X ..... );

이 질문에 대해 지나치게 생각할 때의 원래 답변은 다음과 같습니다.

다중 문자 RS에 GNU awk를 사용하고 각 INSERT 문의 끝에 있는 것처럼 줄 끝에 세미콜론만 있다고 가정합니다.

$ awk 'BEGIN{RS=ORS=";\n"} {print} !(NR%2){print "commit"}' file
INSERT INTO X ..... );
INSERT INTO X ..... );
commit;
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
commit;
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
commit;
INSERT INTO X ..... );

그렇지 않으면 모든 UNIX 시스템의 모든 쉘에서 awk를 사용하십시오.

$ awk '/^INSERT/{ if (c++ == 2) {print "commit;"; c=1} } {print} END{if (c == 2) print "commit;"}' file
INSERT INTO X ..... );
INSERT INTO X ..... );
commit;
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
commit;
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
commit;
INSERT INTO X ..... );

END 부분은 N INSERT 문 뒤가 아닌 N+1 INSERT 문 앞에 삽입되기 때문에 필요하며, 입력에 정확히 N INSERT의 배수가 있는 경우를 처리해야 합니다. 예를 들면 다음과 같습니다.

$ cat file
INSERT INTO X ..... );
INSERT INTO X ..... );
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
INSERT INTO X ..... );
INSERT INTO X ..... );

END 문이 없으면 마지막을 추가할 수 없습니다 commit;.

$ awk '/^INSERT/{ if (c++ == 2) { print "commit;"; c=1 } } {print}' file
INSERT INTO X ..... );
INSERT INTO X ..... );
commit;
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
commit;
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
commit;
INSERT INTO X ..... );
INSERT INTO X ..... );

이것으로 우리는 성공했습니다:

$ awk '/^INSERT/{ if (c++ == 2) { print "commit;"; c=1 } } {print}; END{if (c == 2) print "commit;"}' file
INSERT INTO X ..... );
INSERT INTO X ..... );
commit;
INSERT INTO X .....foo bar
foo bar foo
bar foo
bar);
INSERT INTO X ..... );
commit;
INSERT INTO X ..... );
INSERT INTO X .....foo
bar
foo bar);
commit;
INSERT INTO X ..... );
INSERT INTO X ..... );
commit;

물론 commit;마지막 INSERT 이후에 추가하려는 경우에는 개수에 관계없이 if ( c == 2 )END에서 제거하고 유지하면 됩니다 print.

관련 정보