Discussion:
[shell-script] Adicionar linhas a cada X linhas com variável
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-09-26 14:57:49 UTC
Permalink
Lista,

Estou com um desafio aqui que queria resolver com uma linha de sed ou awk.
Tenho arquivos com milhares de linhas, e preciso adicionar uma nova linha a
cada 200 linhas.
Resolvi com esse sed:

sed -i "0~200 s:$:\nTexto a ser incluido" $filename

O que acontece: eu queria que na frente do "texto a ser incluido"
aparecesse, também, o número daquela linha.
Então na linha 201 eu teria:

Texto a ser incluido 201

e na 402 eu teria:

Texto a ser incluido 402

poderia fazer um loop, qualquer coisa assim. Mas queria resolver da forma
mais sucinta possível
itamarnet@yahoo.com.br [shell-script]
2017-09-26 17:59:23 UTC
Permalink
Boa tarde Alfredo

A solução que tenho seria em awk, e não teria a opção "-i" como no sed para fazer a alteração no próprio arquivo, então seria necessário redirecionar a saída, mas basicamente seria essa a sugestão:


awk '1;NR%200==0{i++;print "Texto a ser incluido", NR+i}' arquivo



Acho que pode usar como uma idéia


[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-09-26 18:33:26 UTC
Permalink
Quase sempre que mando uma pergunta aqui na lista que envolva manipulação
de texto já fico no aguardo da solução do Itamar pq eu sei que vai resolver
kkk
Post by ***@yahoo.com.br [shell-script]
Boa tarde Alfredo
A solução que tenho seria em awk, e não teria a opção "-i" como no sed
para fazer a alteração no próprio arquivo, então seria necessário
awk '1;NR%200==0{i++;print "Texto a ser incluido", NR+i}' arquivo
Acho que pode usar como uma idéia
[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-09-26 20:13:23 UTC
Permalink
Itamar, preciso jogar umas variáveis do bash pra dentro do AWK, pra
formação do texto a ser impresso. Não é tão simples como eu imaginei que
seria.
Estou dentro de um loop e preciso alterar alguns trechos de acordo com as
variaveis do loop!
Post by Alfredo Casanova ***@gmail.com [shell-script]
Quase sempre que mando uma pergunta aqui na lista que envolva manipulação
de texto já fico no aguardo da solução do Itamar pq eu sei que vai resolver
kkk
Post by ***@yahoo.com.br [shell-script]
Boa tarde Alfredo
A solução que tenho seria em awk, e não teria a opção "-i" como no sed
para fazer a alteração no próprio arquivo, então seria necessário
awk '1;NR%200==0{i++;print "Texto a ser incluido", NR+i}' arquivo
Acho que pode usar como uma idéia
[]'s
Itamar
itamarnet@yahoo.com.br [shell-script]
2017-09-26 22:52:57 UTC
Permalink
Caro Alfredo.

Como seria a questão,
1 - Quer ter a opção de mudar o texto que vai ser incluso?
2 - Ou dependendo do ponto no loop o texto incluso pode variar?

Se for a primeira opção pode incluir a opção -v para passar o texto como parametro, exemplo:

awk -v texto="Texto a ser incluido" '1;NR%200==0{i++;print texto, NR+i}' arquivo

ou

variavel='Texto a ser incluido'
awk -v texto="$variavel" '1;NR%200==0{i++;print texto, NR+i}' arquivo


Se for a segunda opção dê alguns exemplos para ilustrar melhor, que dependendo do caso pode haver soluções mais ou menos eficazes.

No agaurdo

[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-09-27 12:46:53 UTC
Permalink
A situação é a seguinte:
Tenho uma lista de parâmetros que passo por xargs para o curl executar de 3
em 3 linhas.
cada linha é +- assim:

-s
http://$url/get.php?parametro1=x\&parametro2=y\&parametro3=TEXTO%20COM%20ESPACOS

o que preciso fazer é a cada 200 linhas adicionar uma linha igual a essa
onde o parametro3 é substituído com uma mensagem no estilo
"PONTO%20DE%20CONTROLE%20${NUMERODALINHA}
Post by ***@yahoo.com.br [shell-script]
Caro Alfredo.
Como seria a questão,
1 - Quer ter a opção de mudar o texto que vai ser incluso?
2 - Ou dependendo do ponto no loop o texto incluso pode variar?
Se for a primeira opção pode incluir a opção -v para passar o texto como
awk -v texto="Texto a ser incluido" '1;NR%200==0{i++;print texto, NR+i}' arquivo
ou
variavel='Texto a ser incluido'
awk -v texto="$variavel" '1;NR%200==0{i++;print texto, NR+i}' arquivo
Se for a segunda opção dê alguns exemplos para ilustrar melhor, que
dependendo do caso pode haver soluções mais ou menos eficazes.
No agaurdo
[]'s
Itamar
itamarnet@yahoo.com.br [shell-script]
2017-09-27 13:44:52 UTC
Permalink
Bom dia Alfredo


Acho que não entendi bem, então me corrija se estiver errado:
O curl recebe paramêtros através do xargs para compor as opções da url a ser consultada.
Esses paramêtros que o xargs repassa estão em alguma variável ou é o conteúdo de algum arquivo?


Imagino que se estiver em um arquivo podemos usar o getline ou usar o ENVIRON se estiver em uma variável exportada, para compor esse texto variável ao longo do registros.


Uma maior detalhamento da forma como esse texto a ser embutido está poderia ajudar numa solução melhor.
Estou focando no AWK, mas talvez outra solução possa ser melhor dependendo do caso.


[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-09-27 13:56:26 UTC
Permalink
Itamar, acho que não fui bem claro.

o arquivo tem milhares de linhas exatamente nesse formato:
$ cat arquivo
-s
http://$url/get.php?parametro1=x\&parametro2=y\&parametro3=TEXTO%20COM%20ESPACOS
<http://%24url/get.php?parametro1=x%5C&parametro2=y%5C&parametro3=TEXTO%20COM%20ESPACOS>
-s
http://$url/get.php?parametro1=x\&parametro2=y\&parametro3=TEXTO%20COM%20ESPACOS
<http://%24url/get.php?parametro1=x%5C&parametro2=y%5C&parametro3=TEXTO%20COM%20ESPACOS>
-s
http://$url/get.php?parametro1=x\&parametro2=y\&parametro3=TEXTO%20COM%20ESPACOS
<http://%24url/get.php?parametro1=x%5C&parametro2=y%5C&parametro3=TEXTO%20COM%20ESPACOS>
...
(obviamente os parâmetros são diferentes em cada linha)

e eu passo para o xargs assim:

cat arquivo | xargs -n2 -P3 -I "{}" bash -c "curl {}"

então o curl executa 3 processos por vez, pegando 2 argumentos por linha
(-s e a url)

o que preciso é, a cada 200 linhas, adicionar algo assim nesse arquivo:

-s http://
$url/get.php?parametro1=x\&parametro2=NOVOPARAMETRO\&parametro3=CONTROLE%20NA%20LINHA%20${LINENUMBER}
Post by ***@yahoo.com.br [shell-script]
Bom dia Alfredo
O curl recebe paramêtros através do xargs para compor as opções da url a
ser consultada.
Esses paramêtros que o xargs repassa estão em alguma variável ou é o
conteúdo de algum arquivo?
Imagino que se estiver em um arquivo podemos usar o getline ou usar o
ENVIRON se estiver em uma variável exportada, para compor esse texto
variável ao longo do registros.
Uma maior detalhamento da forma como esse texto a ser embutido está
poderia ajudar numa solução melhor.
Estou focando no AWK, mas talvez outra solução possa ser melhor dependendo do caso.
[]'s
Itamar
itamarnet@yahoo.com.br [shell-script]
2017-09-27 15:16:01 UTC
Permalink
Alfredo acho que agora entendi

O que pode fazer é usar o getline como mencionei


Baseado no trecho que passou poderia ficar assim:


cat arquivo | xargs -n2 -P3 -I "{}" bash -c "curl {}" | awk '1; NR%200==0 {i++; getline texto < "arquivo"; print texto, NR+i}'



Isso resolve?


Obs.: Fiz um teste com uma massa de dados pequena


[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-10-04 14:10:59 UTC
Permalink
Itamar, desculpe a demora, estava enrolado em outras demandas.
Vou te mostrar um loop que faz exatamente o que eu preciso. Assim vai ficar
mais claro:

ct=0
while read line; do
let ct++
echo $line >> $i.output
(( ct % 200 == 0 )) && {
echo " Mensagem ${numeros[$indice]} - $ct " >> $i.output
}
done < input.txt
Post by ***@yahoo.com.br [shell-script]
Alfredo acho que agora entendi
O que pode fazer é usar o getline como mencionei
cat arquivo | xargs -n2 -P3 -I "{}" bash -c "curl {}" | awk '1;
NR%200==0 {i++; getline texto < "arquivo"; print texto, NR+i}'
Isso resolve?
Obs.: Fiz um teste com uma massa de dados pequena
[]'s
Itamar
itamarnet@yahoo.com.br [shell-script]
2017-10-04 19:22:16 UTC
Permalink
Caro Alfredo,

Se já está fazendo o que você quer então perfeito, mas posso estar enganado mas me parece que a linha adicionada após coloca o mesmo número da linha anterior, ou seja: a linha 200 é impressa e depois vem a mensagem, mas a seguir com o número 200 e não 201, e após a linha 400 segue com 400 também e não 402.
E a mensagem está num array do SHELL e então cada índice do array é a linha correspondente? Ou é sequencial? ou seja:
numero[200]; numero[400]; numero[600]; ...
ou
numero[1]; numero[2]; numero[3]; ...


E as mensagem podem ter espaços no seu conteúdo?


Dependendo de como for dá para usar o awk sem necessidade do getline, mas usando arrays no awk também.


[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-10-04 20:25:02 UTC
Permalink
Ah, a e mensagem tem espaços sim!
Aquele array é só um número que vc pode considerar como aleatório para
qualquer fim.
A numeração da linha não é tão importante. O intuito dessas linhas
adicionadas é servir como "checkpoint" para acompanhar a execução de uma
tarefa. O importante é o $ct estar atualizado (pouco importa se vai mostrar
como 200 ou 201, só preciso ter certeza que a execução alcançou aquele
checkpoint).
Post by ***@yahoo.com.br [shell-script]
Caro Alfredo,
Se já está fazendo o que você quer então perfeito, mas posso estar
enganado mas me parece que a linha adicionada após coloca o mesmo número da
linha anterior, ou seja: a linha 200 é impressa e depois vem a mensagem,
mas a seguir com o número 200 e não 201, e após a linha 400 segue com 400
também e não 402.
E a mensagem está num array do SHELL e então cada índice do array é a
numero[200]; numero[400]; numero[600]; ...
ou
numero[1]; numero[2]; numero[3]; ...
E as mensagem podem ter espaços no seu conteúdo?
Dependendo de como for dá para usar o awk sem necessidade do getline, mas
usando arrays no awk também.
[]'s
Itamar
itamarnet@yahoo.com.br [shell-script]
2017-10-04 21:45:01 UTC
Permalink
Caro Alfredo

Então poderia resumir nisso:

awk -v mens="Mensagem personalizada" '1; NR % 200==0 { print " Mensagem " mens " - " NR }' input.txt > $i.output

Confere?

[]'s
Itamar
Alfredo Casanova atcasanova@gmail.com [shell-script]
2017-10-04 21:54:26 UTC
Permalink
Perfeito! Exatamente isso
Tenho que estudar awk, sempre tem uma magia!
Post by ***@yahoo.com.br [shell-script]
Caro Alfredo
awk -v mens="Mensagem personalizada" '1; NR % 200==0 { print " Mensagem "
mens " - " NR }' input.txt > $i.output
Confere?
[]'s
Itamar
Alyson Franklin alysonfranklinreal@gmail.com [shell-script]
2017-10-04 22:19:30 UTC
Permalink
Itamar é o cara. Entende muito de awk. Já me ajudou algumas vezes e a solução foi exatamente o awk.

Existe algum material de awk, tipo aquele canivete suíno do Aurelio? Ou aquela apostila de Sed do Aurélio, também?

Preciso me aprofundar mais no awk.
Post by ***@yahoo.com.br [shell-script]
Boa tarde Alfredo
awk '1;NR%200==0{i++;print "Texto a ser incluido", NR+i}' arquivo
Acho que pode usar como uma idéia
[]'s
Itamar
itamarnet@yahoo.com.br [shell-script]
2017-10-06 11:23:49 UTC
Permalink
Obrigado Alyson pela referência

Mas o melhor site que tinha sobre awk não existe mais: awk.info


O que posso recomendar é o site do gawk que a versão gnu:
https://www.gnu.org/software/gawk/manual/ https://www.gnu.org/software/gawk/manual/



Tem também o mawk, que eu particularmente não gosto. É como comparar o bash com o dash
http://invisible-island.net/mawk/ http://invisible-island.net/mawk/



Referência nacional e inquestionável é o livro do mestre Júlio:
http://www.brasport.com.br/informatica-e-tecnologia/linux/programacao-shell-linux-11/ http://www.brasport.com.br/informatica-e-tecnologia/linux/programacao-shell-linux-11/



Ou da O'Reilly:
https://www.amazon.com.br/Effective-awk-Programming-Universal-Processing-ebook/dp/B00U8232XM/ref=pd_sim_351_7?_encoding=UTF8&psc=1&refRID=9C969TMTTZXZRV4MZDRV https://www.amazon.com.br/Effective-awk-Programming-Universal-Processing-ebook/dp/B00U8232XM/ref=pd_sim_351_7?_encoding=UTF8&psc=1&refRID=9C969TMTTZXZRV4MZDRV



E dois sites que recomendo em português:
http://matheuslion.blogspot.com.br/2012/11/awk-tutorial-o-melhor.html http://matheuslion.blogspot.com.br/2012/11/awk-tutorial-o-melhor.html

http://www.inf.pucrs.br/manssour/AWK/index.html http://www.inf.pucrs.br/manssour/AWK/index.html







---Em shell-***@yahoogrupos.com.br, <***@...> escreveu:

Itamar é o cara. Entende muito de awk. Já me ajudou algumas vezes e a solução foi exatamente o awk.

Existe algum material de awk, tipo aquele canivete suíno do Aurelio? Ou aquela apostila de Sed do Aurélio, também?

Preciso me aprofundar mais no awk.


Em 26 de set de 2017 14:59 -0300, ***@... [shell-script] <shell-***@...> escreveu:
Boa tarde Alfredo


A solução que tenho seria em awk, e não teria a opção "-i" como no sed para fazer a alteração no próprio arquivo, então seria necessário redirecionar a saída, mas basicamente seria essa a sugestão:


awk '1;NR%200==0{i++;print "Texto a ser incluido", NR+i}' arquivo



Acho que pode usar como uma idéia


[]'s
Itamar

Continue reading on narkive:
Loading...