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.