Como eu posso adicionar algum texto depois de alguma seqüência de texto se esta seqüência corresponder a certos critérios usando o script Shell?

0

Eu quero adicionar uma declaração logo após o texto corresponder às condições mencionadas em um script de shell,

Abaixo está o meu arquivo de amostra (arquivo 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;

Vou pegar esse arquivo e fazer a transformação abaixo, Depois de ver qualquer um dos textos abaixo na sequência

1: "UPDATE ... SET ...;"
2: "DELETE ... FROM ...;"
3: "INSERT ... INTO ...;"
4: "MERGE ... INTO ... [WHEN MATCHED THEN | WHEN NOT MATCHED] ... [UPDATE|INSERT|DELETE] ... ;"

Eu preciso adicionar uma linha extra logo após o ponto-e-vírgula

AFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;

Então, meu novo arquivo será parecido com algo abaixo

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;

Eu tentei encontrar e implementar a abordagem no escopo do PLSQL, mas não encontrei nenhuma maneira genérica possível para obter o número de linhas afetadas, então pensei de análise de texto, mas eu não sei muito sobre awk ou sed.

Por enquanto, o que eu estava tentando fazer é algo como abaixo:

sed '/ Padrões Go Here / a AFFECTED_ROWS: = AFFECTED_ROWS + SQL% ROWCOUNT;' temp.sql

Então, o padrão pode ter condições mencionadas acima

    
por Hargun Suri 25.10.2018 / 00:39

1 resposta

1

Eu o resolvi usando perl ao invés de sed e usando a variável especial IRS (Input Record Separator - $ /) para processar linhas por ponto e vírgula, em vez de por nova linha.

Qualquer linguagem que suporte a mudança do IRS deve funcionar (provavelmente possível com o bash puro usando IFS=';' , mas eu não explorei isso).

Neste exemplo, o perl carregará seu buffer até o separador de registro de entrada e processará todo esse conteúdo como uma linha - alterando o que é esse separador, você pode processar o arquivo uma instrução de cada vez, em vez de uma linha em um tempo. Então, posso corresponder ao padrão da (s) instrução (ões) em que estou interessado e anexar a lógica das linhas afetadas à linha antes de ser impressa.

$ 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;

$

Usando menos abreviações por perl, você pode fazer isso:

perl -e '$/=";"; foreach $statement (<>){ print $statement; $statement =~ m/(MERGE INTO .*)|(DELETE FROM)/i && print "\nAFFECTED_ROWS := AFFECTED_ROWS + SQL%ROWCOUNT;" }'

por exemplo:

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;
$
    
por 25.10.2018 / 02:00