Manipular arquivo texto e para gerar comandos sed.

Linux

ShellScript

11/03/2023

Olá pessoal, alguém consegue ajudar?

Tenho um arquivo texto com o seguinte conteúdo (formado com 3 colunas): 1ª coluna é um caminho para um arquivo, a 2ª coluna é o nº da linha dentro do arquivo e a 3ª o conteúdo da linha.

Se o nome do arquivo se repetir, ou seja, se ele tiver mais de uma ocorrência, está em sequência e o número da linha sempre da menor para a maior.

Exemplo:

/tmp/teste1/arq1.conf:99:string 3
/tmp/teste2/arq1.conf:103:string 1
/tmp/teste2/arq1.conf:122:string qualquer
/tmp/teste2/arq1.conf:115:abracadabra teste
/tmp/teste3/arq1.conf:106:abcde
/tmp/teste3/arq1.conf:155:ola mundo
/tmp/teste4/arq1.conf:60:string qualquer 2
/tmp/teste5/arq1.conf:10:ola mundo

Reparem que podem ter mais de uma linha para o mesmo arquivo e este arquivo é gerado dinamicamente.

A partir dele, preciso gerar uma saída contendo comandos sed de alteração em cada arquivo desta lista da seguinte forma:
Se o nome do arquivo tiver somente uma ocorrência (ex. /tmp/teste1/arq1.conf, /tmp/teste4/arq1.conf e /tmp/teste5/arq1.conf) ou várias ocorrências mas sendo a última, gerar o sed para substituir o conteúdo da linha por uma string pré-definida.
Se o arquivo tiver mais ocorrência mas NÃO é a última na sequência, gerar o sed para remover a linha e este comando deve estar depois dos comandos de substituição.

Digamos que se a string de substituição for xpto, a saída deveria ser igual a:

sed -i "99s/.*/xpto/g" /tmp/teste1/arq1.conf
sed -i "115s/.*/xpto/g" /tmp/teste2/arq1.conf
sed -i "103d" /tmp/teste2/arq1.conf
sed -i "122d" /tmp/teste2/arq1.conf
sed -i "155s/.*/xpto/g" /tmp/teste3/arq1.conf
sed -i "106d" /tmp/teste3/arq1.conf
sed -i "60s/.*/xpto/g" /tmp/teste4/arq1.conf
sed -i "10s/.*/xpto/g" /tmp/teste5/arq1.conf

De preferência, se for através de awk (ou sed se possível) seria melhor ainda porque não queria loops for / while.
Luiz Gustavo

Luiz Gustavo

Curtidas 0

Respostas

Arthur Heinrich

Arthur Heinrich

11/03/2023

Você pode acessar o arquivo com o comando "tac", que lê o arquivo do fim para o começo. Assim, se o arquivo lido for diferente do anterior, monta a linha do update. Se for igual, monta o delete.
GOSTEI 0
Luiz Gustavo

Luiz Gustavo

11/03/2023

Oi Arthur, obrigado pela sugestão, mas no caso de ter 3 iguais, ele fará o delete deles e o último dele (no caso do primeiro por causa do tac) precisa ser update.
GOSTEI 0
Arthur Heinrich

Arthur Heinrich

11/03/2023

Oi Arthur, obrigado pela sugestão, mas no caso de ter 3 iguais, ele fará o delete deles e o último dele (no caso do primeiro por causa do tac) precisa ser update.


Exatamente. Foi o que eu disse.
Você faz um loop invertido e compara o nome do arquivo de cada linha, com o nome do arquivo da linha anterior. Se for diferente, monta o update. Se for igual, monta o delete

LINHA                                       ARQ. ANT.             COMANDO
------------------------------------------- --------------------- -------
/tmp/teste5/arq1.conf:10:ola mundo                                update
/tmp/teste4/arq1.conf:60:string qualquer 2  /tmp/teste5/arq1.conf update
/tmp/teste3/arq1.conf:155:ola mundo         /tmp/teste4/arq1.conf update
/tmp/teste3/arq1.conf:106:abcde             /tmp/teste3/arq1.conf delete
/tmp/teste2/arq1.conf:115:abracadabra teste /tmp/teste3/arq1.conf update
/tmp/teste2/arq1.conf:122:string qualquer   /tmp/teste2/arq1.conf delete
/tmp/teste2/arq1.conf:103:string 1          /tmp/teste2/arq1.conf delete
/tmp/teste1/arq1.conf:99:string 3           /tmp/teste2/arq1.conf update

GOSTEI 0
Arthur Heinrich

Arthur Heinrich

11/03/2023

Eu inverti as linhas errado no exemplo anterior, mas a lógica está correta:
LINHA                                       ARQ. ANT.             COMANDO
------------------------------------------- --------------------- -------
/tmp/teste5/arq1.conf:10:ola mundo                                update
/tmp/teste4/arq1.conf:60:string qualquer 2  /tmp/teste5/arq1.conf update
/tmp/teste3/arq1.conf:155:ola mundo         /tmp/teste4/arq1.conf update
/tmp/teste3/arq1.conf:106:abcde             /tmp/teste3/arq1.conf delete
/tmp/teste2/arq1.conf:122:string qualquer   /tmp/teste3/arq1.conf update
/tmp/teste2/arq1.conf:115:abracadabra teste /tmp/teste2/arq1.conf delete
/tmp/teste2/arq1.conf:103:string 1          /tmp/teste2/arq1.conf delete
/tmp/teste1/arq1.conf:99:string 3           /tmp/teste2/arq1.conf update

GOSTEI 0
Luiz Gustavo

Luiz Gustavo

11/03/2023

Obrigado Arthur, pelas idéias. Consegui fazer com awk usando array.
GOSTEI 0
POSTAR