Shell Script - Como adicionar novas palavras dentro de uma String?

1. Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendinoLinux

(usa Ubuntu)

Enviado em 17/08/2011 - 20:30h

Como eu posso fazer para adicionar novas palavras de texto dentro de uma String que tem sempre o mesmo padrão.

exemplo:

20110816123500111321565654034.csv
2011081612350011132156565403.csv
2011081612350011124556565404.csv
2011081612350011104515656540.csv

Onde os 4 primeiros caracteres são relativas ao ano, 2 ao mês, dia, etc..

A frase a ser montada para cada linha usando a primeira linha de exemplo seria:
----------------
No dia [16] de [Agosto 08] de [2011], você fez [123] pontos. Você recebeu [500] pontos de bonificação. Faltam [111] dias para encerrar tarefas. Seu principal concorrente tem [32156] pontos acumulados. Seu registro é 5654034
----------------
Eu tentei fazer a inclusão dos nomes com sed, dancei.
Talvez fazendo um while pode ser que funciona. Tenho a impressão que o ideal seria o sed ou outro qualquer para montar uma nova string com base na linha demonstrada.
Tô perdido rsrs. Quem pode ajudar no caminho das pedras ?


Obrigado

@Ga_Tux


  


2. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendinoLinux

(usa Ubuntu)

Enviado em 17/08/2011 - 22:55h

Resolvido na base da POG.

---- fiz um for pegando os trechos.

for i in $(cat ${_TMP_ARQ_TRAB1})
do
_TMP___DATA=$(echo "$i" |cut -c-4)
_TMP____MES=$(echo "$i" |cut -c5-6)
_TMP____DIA=$(echo "$i" |cut -c7-8)
_TMP___HORA=$(echo "$i" |cut -c9-10)
_TMP_MINUTO=$(echo "$i" |cut -c11-12)
....etc...
------ fim.

Não gostei, mas tá funcionando.

Reclamações contra a POG.

Se o arquivo tiver 1.000 linhas eu vou fazer cat 1.000 vezes e também 1.000 for ?

Como fazer pra jogar o arquivo na memória e depois fazer todas interações de loop seja de for ou while ?

Situações como estas não seriam melhor processadas usando array se ele não for grande, tipo até umas 1.000 linhas ?

O que é melhor, o que é pior ? Alguma dica ?

Obrigado.

oops. se o tonto falou alguma besteira avisem rsrs.



3. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Raimundo Alves Portela
rai3mb

(usa Outra)

Enviado em 17/08/2011 - 23:00h

Se os valores tiverem as posições fixas, pode fazer assim:

ANO=$(echo "2011081612350011124556565404" | cut --bytes=1-4)
MES=$(echo "2011081612350011124556565404" | cut --bytes=5-6)
DIA=$(echo "2011081612350011124556565404" | cut --bytes=7-8)
SEUS_PONTOS=$(echo "2011081612350011124556565404" | cut --bytes=9-11)
PONTOS_BONIFICACAO=$(echo "2011081612350011124556565404" | cut --bytes=12-14)
FALTAM_DIAS=$(echo "2011081612350011124556565404" | cut --bytes=15-17)
PONTOS_CONCORRENTES=$(echo "2011081612350011124556565404" | cut --bytes=18-22)
REGISTRO=$(echo "2011081612350011124556565404" | cut --bytes=23-29)

Agora o ideal mesmo é colocar um separador no momento de gerar esses valores, por exemplo:

2011|08|16|123|500|111|24556|565404

vai fica mamão com açúcar :-)

ANO=(echo "2011|08|16|123|500|111|24556|565404" | cut -d'|' -f1)


Usar o sed, deve até dar certo, mas é um problema simples que dar para resolver com o cut.

Abraços




4. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Raimundo Alves Portela
rai3mb

(usa Outra)

Enviado em 17/08/2011 - 23:03h

o conteúdo que você quer fica nas linhas do arquivo? se sim, faça

while read LINHA;
do


....

done < arquivo.csv

ABraços


5. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

euteste da silva
foxbit3r

(usa Solaris)

Enviado em 18/08/2011 - 00:06h

Olha aí se resolve.
Salva os dados num arquivo e chama o awk assim:

awk '{

ANO=substr($0,0,4)
MES=substr($0,5,2)
DIA=substr($0,7,2)
PONTOS=substr($0,9,3)
RPONTOS=substr($0,12,3)
FPONTOS=substr($0,15,3)
CPONTOS=substr($0,18,5)
REG=substr($0,23)
gsub(/[^0-9]/,"",REG)
printf("Ano = %s ",ANO)
printf("Mes = %s ", MES)
printf("Dia = %s ", DIA)
printf("Pontos = %s ", PONTOS)
printf("Recebidos = %s ", RPONTOS)
printf("Faltam = %s ", FPONTOS)
printf("Concorrentes = %s ", CPONTOS)
printf("Reg = %s\n ", REG)
}' arquivo.txt


6. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 18/08/2011 - 07:09h

ok @rai3mb

[citando]
Agora o ideal mesmo é colocar um separador no momento de gerar esses valores, por exemplo:

2011|08|16|123|500|111|24556|565404

vai fica mamão com açúcar :-)

ANO=(echo "2011|08|16|123|500|111|24556|565404" | cut -d'|' -f1)
[/citando]

Eu recebo os arquivos nos diretórios já prontos e o nome deles me dizem o conteúdo. 20110816123500111321565654034.csv,
2011081612350011132156565403.csv,2011081612350011124556565404.csv,2011081612350011104515656540.csv


Olá @foxbit3r , vou tentar esta sua solução em awk
[citando]
awk '{

ANO=substr($0,0,4)
MES=substr($0,5,2)
DIA=substr($0,7,2)
PONTOS=substr($0,9,3)
RPONTOS=substr($0,12,3)
FPONTOS=substr($0,15,3)
CPONTOS=substr($0,18,5)
REG=substr($0,23)
gsub(/[^0-9]/,"",REG)
printf("Ano = %s ",ANO)
printf("Mes = %s ", MES)
printf("Dia = %s ", DIA)
printf("Pontos = %s ", PONTOS)
printf("Recebidos = %s ", RPONTOS)
printf("Faltam = %s ", FPONTOS)
printf("Concorrentes = %s ", CPONTOS)
printf("Reg = %s\n ", REG)
}' arquivo.txt
[/citando]

A minha intenção era tentar fazer tudo na hora que estou pegando os arquivos e já gerar a saída para os outros formatadas com as mensagens.
Estou percebendo que só será possível em 3 etapas. Queria uma solução mais eficiente.
Se entendi corretamente, em awk a solução seria em duas etapas.

1-varrer o diretório com ls gerando um arquivo com os nomes, linha por linha.
2-Rodar awk gerando os arquivos de saida já formatados e com os conteúdos prontos.

Vou tentar.

Sugestões sempre bem vindas :)

Lembrando que a saída é formatada com os dados. Se eu não conseguir gerar as mensagens na 2ª etapa, vou ter que ter 3 processamentos.

[citando]
----------------
No dia [16] de [Agosto 08] de [2011], você fez [123] pontos. Você recebeu [500] pontos de bonificação. Faltam [111] dias para encerrar tarefas. Seu principal concorrente tem [32156] pontos acumulados. Seu registro é 5654034
----------------
[/citando]


7. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 18/08/2011 - 07:33h

O conteúdo é fixo até um determinado ponto @rai3mb e não tenho acesso a geração do arquivo, já vem pronto no diretório feito por outro sistema.

20110816123500111321565654034.csv
fixo="2011|08|16|123|500|111|32156"
variando=[vai de 1 a 9999999999] + . extensão.

O cenário ideal seria:

Quando rodar o ls pegando todos os 100 ou 1000 arquivos, já gerar a saída formatada para um arquivo ou para todos os arquivos prontos com as mensagens de envio.
Se conseguir pegar o ls formatando, já serve. Jogaria em um arquivo os dados formatados e uma outra rotina pegaria eles e incluiria as mensagens.
Mas o ideal seria após ler o diretório usando um arquivo pronto em memória com todas as informações formatadas.

Tentando a opção awk rsrs. Nunca usei ele.




8. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 18/08/2011 - 08:20h

Olá @foxbit3r , tentando awk e parece que vai dar certinho rs.
Está gerando na tela assim:

------------
_TMP_ARQ_TRAB1="${_DIR_ATUAL}/tmp_${$}.tmp"

ls -x -1 *.csv | awk '{
ANO=substr($0,0,4)
MES=substr($0,5,2)
DIA=substr($0,7,2)
PONTOS=substr($0,9,3)
RPONTOS=substr($0,12,3)
FPONTOS=substr($0,15,3)
CPONTOS=substr($0,18,5)
REG=substr($0,23)
gsub(/[^0-9]/,"",REG)
printf("Ano = %s ",ANO)
printf("Mes = %s ", MES)
printf("Dia = %s ", DIA)
printf("Pontos = %s ", PONTOS)
printf("Recebidos = %s ", RPONTOS)
printf("Faltam = %s ", FPONTOS)
printf("Concorrentes = %s ", CPONTOS)
printf("Reg = %s\n ", REG )
}'
-----------
Mas quando eu tento colocar a saída para o arquivo $_TMP_ARQ_TRAB1 tá dando pau.

[citando]

awk: lin. de com.:17: printf("Reg = %s\n ", REG ) >> ( ${_TMP_ARQ_TRAB1} )
awk: lin. de com.:17: ^ syntax error
awk: lin. de com.:18: printf("Reg = %s\n ", REG ) >> ( ${_TMP_ARQ_TRAB1} )
awk: lin. de com.:18: ^ fim de linha ou de string inesperado
[/citando]

---------------

_TMP_ARQ_TRAB1="${_DIR_ATUAL}/tmp_${$}.tmp"

ls -x -1 *.csv | awk '{
ANO=substr($0,0,4)
MES=substr($0,5,2)
DIA=substr($0,7,2)
PONTOS=substr($0,9,3)
RPONTOS=substr($0,12,3)
FPONTOS=substr($0,15,3)
CPONTOS=substr($0,18,5)
REG=substr($0,23)
gsub(/[^0-9]/,"",REG)
printf("Ano = %s ",ANO)
printf("Mes = %s ", MES)
printf("Dia = %s ", DIA)
printf("Pontos = %s ", PONTOS)
printf("Recebidos = %s ", RPONTOS)
printf("Faltam = %s ", FPONTOS)
printf("Concorrentes = %s ", CPONTOS)
printf("Reg = %s\n ", REG ) >> ( ${_TMP_ARQ_TRAB1} )
}'
-----------------
Já tentei colocar aspas em torno da variável, tirar os parenteses, mudar de lugar dentro da chave após o REG.
Deve ser alguma coisa bem simples rsrs, mas como nunca usei awk...
oops: Ainda não tentei colocar as strings em torno das variáveis pra gerar a saída, mas já percebi que esta construção deverá dar certo.




9. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 18/08/2011 - 08:56h

oops, última forma, funcionando :)

---------

_TMP_ARQ_TRAB1="${_DIR_ATUAL}/tmp_${$}.tmp"

ls -x -1 *.csv | awk '{
_TMP_COMAND="[SeuProgGerador]"
ANO=substr($0,0,4)
MES=substr($0,5,2)
DIA=substr($0,7,2)
PONTOS=substr($0,9,3)
RPONTOS=substr($0,12,3)
FPONTOS=substr($0,15,3)
CPONTOS=substr($0,18,5)
REG=substr($0,23)
gsub(/[^0-9]/,"",REG)
printf("%s ",_TMP_COMAND)
printf("%s ",ANO)
printf("%s ", MES)
printf("%s ", DIA)
printf("Pontos = %s ", PONTOS)
printf("Recebidos = %s ", RPONTOS)
printf("Faltam = %s ", FPONTOS)
printf("Concorrentes = %s ", CPONTOS)
printf("Reg = %s\n",REG ) } ' >> "$_TMP_ARQ_TRAB1"

--------------


10. Re: Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 18/08/2011 - 09:00h

Em breve a solução final e o código como ficará. RESOLVIDO :)


11. SOLUÇÃO Shell Script - Como adicionar novas palavras dentro de uma String?

Geraldo Albuquerque
AprendiNoLinux

(usa Ubuntu)

Enviado em 18/08/2011 - 09:44h

Antes da ajuda do pessoal, a solução era.

1- gerar um arquivo temporário usando ls.
2 - Carregar o arquivo temporário com um cat
3 - No cat realizar um for para gerar outro arquivo de saída.
4 - O loop gerado no for tinha acesso ao arquivo gravado temporário várias vezes.

Como ficou.

1 - Continua sendo feito o ls.
2 - Passado a um novo shell com os dados na memória para o awk
3 - Processo em memória gera o tratamento.
4 - Saída final em arquivo formatado (que na verdade serão comandos para outro processamento.

Se eu estiver errado, por favor corrigir.

Ganhos. Se eu tiver 1.000 arquivos agora o processamento será em memória e somente no final descarregado em disco.
Em vez de gerar 3 temporários, agora só gero 1 e este nem será preciso quando for conectado a outro comando.

------------------------------------------------
# Diretório atual + tmp + tipo de trabalho + processo + extensão tmp.
_TMP_MENSAGENS="${_DIR_ATUAL}/tmp_mensagens_${$}.tmp"

# Parametros que virão de outra rotina.
_COMANDO="ls "
_ORDEM_SAIDA=" -x -1 "
_MASCARA=" *"
_EXTENSAO_ARQ=".csv"
_GERA_COMANDO="${_COMANDO}${_ORDEM_SAIDA}${_MASCARA}${_EXTENSAO_ARQ}"

# Abaixo a chamada de script que vai disparar as mensagens.
_TMP_COMAND="[SeuProgGerador]"

# Reduzido O exemplo abaixo para entender a solução final.
#No dia [16] de [Agosto 08] de [2011], você fez [123] pontos.
# O mês eu vou arrumar com uma função depois.

$_GERA_COMANDO | awk '{
_TMP_COMAND="[SeuProgGerador]"
MSG[0]="No dia "
MSG[1]="de"
MSG[2]=",você fez"
MSG[3]="pontos."
ANO=substr($0,0,4)
MES=substr($0,5,2)
DIA=substr($0,7,2)
PONTOS=substr($0,9,3)
gsub(/[^0-9]/,"",REG)
printf("%s ",_TMP_COMAND)
printf("%s", MSG[0])
printf("%s ", DIA)
printf("%s ", MSG[1])
printf("%s ", MES)
printf("%s ", MSG[2])
printf("%s ", PONTOS)
printf("%s ", MSG[3])
printf("%s\n",REG ) } ' >> "$_TMP_MENSAGENS"
-------------------
Obrigado ao @rai3mb pela ajuda inicial.

A solução proposta pelo @foxbit3r foi a melhor para este caso. Parabéns, aprendi mais uma :)

@GA_Tux

Prova do crime:

1ª versão que fazia ls, cat, for: [ real 1.593 user 0.060 sys 0.110 pcpu 10.66 ]
2ª versão ls + awk em memória: [real 0.014 user 0.000 sys 0.000 pcpu 0.00]

Imagine se você tem que fazer isto cerca de 100.000 vezes ao dia. Faz uma diferença enorme.









Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts