쉘 스크립트 사용에 대한 특정 기준을 충족하는 경우 일련의 텍스트 뒤에 텍스트를 추가하려면 어떻게 해야 합니까?

쉘 스크립트 사용에 대한 특정 기준을 충족하는 경우 일련의 텍스트 뒤에 텍스트를 추가하려면 어떻게 해야 합니까?

쉘 스크립트에 언급된 조건과 일치하는 텍스트 뒤에 명령문을 추가하고 싶습니다.

다음은 내 샘플 파일(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;
$

관련 정보