쉘 스크립트에 언급된 조건과 일치하는 텍스트 뒤에 명령문을 추가하고 싶습니다.
다음은 내 샘플 파일(SQL 파일)입니다.
begin
AFFECTED_ROWS := 0;
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
DELETE FROM table_name
WHERE condition;
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
end;
다음 텍스트 중 하나가 순서대로 표시되면 이 파일을 가져와 다음 변환을 수행합니다.
1: "UPDATE ... SET ...;"
2: "DELETE ... FROM ...;"
3: "INSERT ... INTO ...;"
4: "MERGE ... INTO ... [WHEN MATCHED THEN | WHEN NOT MATCHED] ... [UPDATE|INSERT|DELETE] ... ;"
세미콜론 뒤에 한 줄을 추가해야 합니다
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
내 새 파일은 다음과 같습니다.
begin
AFFECTED_ROWS := 0;
UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
DELETE FROM table_name
WHERE condition;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
INSERT INTO table_name (column1, column2, column3, ...)
VALUES (value1, value2, value3, ...);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
end;
PLSQL 범위에서 메서드를 찾아 구현하려고 했지만 행에 영향을 주지 않게 할 수 있는 일반적인 메서드를 찾지 못해 텍스트 구문 분석을 생각했지만 awk나 sed에 대해 잘 모릅니다.
이제 나는 다음과 같은 일을 하려고 합니다.
sed '/Patterns Go Here/a AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;'임시 sql
따라서 패턴은 위에서 언급한 조건을 가질 수 있습니다.
답변1
sed 대신 perl을 사용하고 IRS(입력 레코드 구분 기호 - $/) 특수 변수를 사용하여 줄 바꿈 대신 세미콜론이 있는 줄을 처리함으로써 문제를 해결했습니다.
IRS 변경을 지원하는 모든 언어가 작동해야 합니다( 순수 bash를 사용하여 가능할 수도 있지만 IFS=';'
아직 살펴보지 않았습니다).
이 예에서 Perl은 레코드 구분 기호가 입력될 때까지 버퍼를 로드한 다음 모든 것을 단일 라인으로 처리합니다. 구분 기호의 내용을 변경하면 한 번에 한 라인 대신 한 번에 하나의 명령문을 처리할 수 있습니다. 그런 다음 관심 있는 문의 패턴을 일치시키고 인쇄하기 전에 영향을 받는 줄을 해당 줄에 논리적으로 추가할 수 있습니다.
$ cat test.sql
SELECT non-matching-statement FROM table;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
SELECT another-non-matching-statement FROM table;
end;
$ cat test.sql | perl -pe 'BEGIN{$/=";"} m/MERGE INTO .*/ && ($_ .= "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL %ROWCOUNT;")'
SELECT non-matching-statement FROM table;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
SELECT another-non-matching-statement FROM table;
end;
$
Perl 속기를 덜 사용하면 다음과 같이 할 수 있습니다:
perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'
예를 들어:
cat test.sql | perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'
SELECT non-matching-statement FROM table;
MERGE INTO employees e
USING hr_records h
ON (e.id = h.emp_id)
WHEN MATCHED THEN
UPDATE SET e.address = h.address
WHEN NOT MATCHED THEN
INSERT (id, address)
VALUES (h.emp_id, h.address);
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
SELECT another-non-matching-statement FROM table;
DELETE FROM truncate_me;
AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;
end;
$