shell-script-pt
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [shell-script] Re: [Shell] - Ajuda


From: Victor Salustrino Bezerra
Subject: Re: [shell-script] Re: [Shell] - Ajuda
Date: Mon, 1 Aug 2016 09:03:02 -0300

Vinícius, bom dia!

Desculpe a demora para responder, só vi o e-mail hoje, segunda-feira.

Pois bem, vou esmiuçar o comando e tentar explicar a ideia.

sed -r "s/(^\".*\" \".*\" \".*\" \".*\" \")2(\" \".*\"$)/\13\2/g"



s/<expressão_regular>/<string_substituta>/g

Onde:

s: comando do sed para fazer a substituição de tudo que casar com a <expressão regular> por <string_substituta>

/: separador dos comandos

<expressão_regular>: expressão que busca o conteúdo que será substituído

<string_substituta>: conteúdo que será colocado no lugar das ocorrências da expressão regular

g: força o sed a executar a substituição até o final da linha, mesmo já tendo encontrado uma ocorrência da ER. Quando não é utilizado, o sed passa para a próxima linha depois que casou o primeiro grupo de caracteres. Eu costumo usar o g em todos os comandos.


A estratégia que eu utilizei foi fazer uma expressão regular que case a linha inteira, marcando com parênteses os trechos que eu vou manter e então usar na string substituta um retrovisor para o trecho em parênteses. Desta forma eu garanto que vou substituir apenas o conteúdo do quinto campo.

Partindo do modelo de linha no arquivo:

"2885" "2" "50" "ALO" "2" "3"

1) Montar a <expressão_regular>

Primeira etapa, marcar o início e o fim da linha com ^ e $.

^"2885" "2" "50" "ALO" "2" "3"$

Segunta etapa, substituir o conteúdo de cada campo por .*, que significa qualquer símbolo em qualquer quantidade. Não substituí o conteúdo do quinto campo, pois quero encontrar as linhas cujo campo de posição 5 é igual a 2

^".*" ".*" ".*" ".*" "2" ".*"$

A terceira etapa é marcar os trechos que são acessados pelos retrovisores, um recurso que serve para selecionar um trecho da expressão regular que foi "casado". Para isto é preciso marcar o trecho com o uso de parênteses. É como se você estivesse copiando o trecho em parênteses para usar depois. No seu caso eu marquei todo o trecho antes do 2, assim como todo o trecho depois dele.

(^".*" ".*" ".*" ".*" ")2(" ".*"$)

A quarta etapa é proteger as aspas com o \, para não serem interpretadas como o fim da instrução e obter o resultado final

(^\".*\" \".*\" \".*\" \".*\" \")2(\" \".*\"$)


2) Montar a <string_substituta>
\1: corresponde ao primeiro trecho marcado entre parênteses, isto é o retrovisor
3 : este é o valor que vai substituir o 2
\2: corresponde ao segundo trecho marcado entre parênteses

\13\2


Obs: o comando sed precisa do -r para executar retrovisores

Agora tem que substituir tudo no comando,
sed -r "s/<expressão_regular>/<string_substituta>/g" teste.txt

ficando:

sed -r "s/(^\".*\" \".*\" \".*\" \".*\" \")2(\" \".*\"$)/\13\2/g" teste.txt

Não achei na internet a explicação de retrovisor, mas sei que no livro do Julio Cezar Neves tem.

Espero ter ajudado.


Em 1 de agosto de 2016 00:47, address@hidden [shell-script] <address@hidden> escreveu:
 

hum o separador de campos na saída rs não me lembrei mesmo, por isso
aquela gambiarra toda pra imprimir o FS entre os campos.
Valeu a dica, Itamar, é bom saber as variáveis do awk, simplifica bastante.
Abraços Paulo Bettega

On 31-07-2016 22:16, address@hidden [shell-script] wrote:
>
>
> Tem razão Paulo
>
> Eu não havia percebido esse detalhe.
>
> Acabei me esquecendo de incluir um trecho no código no bloco BEGIN
>
> awk -F '" "' 'BEGIN { OFS=FS }; $5=="2" { sub("2","3",$5) }; 1'
>
> Isso que seria o correto na sugestão anterior.
> Desculpe-me, postei sem testar.
>
> []'s
> Itamar
>
>
> ----------------------------------------------------------
> Enviado por: address@hidden
> ----------------------------------------------------------




--
Victor Salustrino Bezerra

reply via email to

[Prev in Thread] Current Thread [Next in Thread]