Filtrar um arquivo e criar outro [RESOLVIDO]

1. Filtrar um arquivo e criar outro [RESOLVIDO]

Lincoln Oliveira de Souza
lincolnsol

(usa Fedora)

Enviado em 30/09/2009 - 01:43h

Boa noite amigos do forum

estou tentando"filtrar" um arquivo texto com mais de 900 linha e criar varios arquivos pequenos, poremarquivos organizados e que eu consigafazer calculos com ele.

O que eu preciso fazer é :

1° - Encontrar a astring "<H2>" e a string "<H3>" dentro do arquivo.

2° - O script copia as linhas entre as duas strings para o outro arquivo(arquivo de saida)
se a string "<H2>" estiver na linha 6 e a string "<H3>" estiver na linha 32, o arquivo de saida é criado contendo da linha 7 até a linha 31

3° - O nome do arquivo de saida está sempre na linha que começa com a strig "<H2>"
Exemplo de uma linha que começe com a string "<H2>" :
"<H2>82965 SBAT Alta Floresta (Aero) Observations at 12Z 12 Nov 1988</H2>"
Do 5° ao 9° caracter underline do 16° ao 28° caracter underline do 53° ao 67° caracter.txt
82965_Alta Floresta_12Z 12 Nov 1988.txt

4° - Como o arquivo matriz tem umas 900 linhas esse processo deve ser repetido até o arquivo matriz acabar.

5° - Na pasta onde o arquivo matriz está existem muitos arquivos, e o processo deve ser feito em todos eles(criar loop).

6° - Depois de terminar um arquivo o script deve passar para o proximo arquivo da pasta, e assim sucessivamente até acabar os arquivos da apasta.

[exemplo de arquivo matriz]
http://www.4shared.com/file/132893608/232e19eb/sounding_30_.html

A minha ideia foi criar um while dentro de um if usando o comando grep:
if grep ... pra achar a 1° string
while grep ... pra achar a segunda string

dai com o if o script acha a 1° string e começa a copiar as linhas para o arquivo de saida, e com o while o script vai testando se a 2°string está na proxima linha e enquanto ela não aparecer o script continua copiando as linhas para o arquivo de saida.

Desde já eu agradeço a ajuda de todos, e se o caminho q eu estiver seguindo for errado por favor me ajudem a achar um caminho certo


  


2. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

Lincoln Oliveira de Souza
lincolnsol

(usa Fedora)

Enviado em 30/09/2009 - 13:53h

Bem gente eu desisiti de usar um WHILE dentro de um IF

mas acredito q usando um IF dentro de outro IF eu consiga resolver o problema
--------------------------------
#!/bin/bash
caminho="/home/Lincoln/Scripts"
string1="<H2>"
string2="<H3>"
arq="sounding(30).txt"
arqfinal="teste.txt"

echo 'Limpando a tela...'
sleep 1
clear
rm -f $arqfinal

if grep $string1 $arq ; then

if -ne grep $string2 $arq ; then
echo $string1 $string2
fi
fi

Qual comando eu uso para q as linhas depois da 1° string sejam copiadas para oarquivo desaida ?O proprio grep faz isso ? Por favor me ajudem


3. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 01/10/2009 - 18:10h

Cara, infelizmente não consigo acessar o seu arquivo modelo, mas se eu entendi bem sua questão, isso aqui deve resolver ... mas se tiver algum problema, não for isso ou der erro, avisa.



#-----------------------------------
# CORTA ARQUIVO
#-----------------------------------
# Preencha as informacoes abaixo

arquivo_de_saida="sai" # Serao numerados ex.: sai1, sai2 ...
arquivo_de_entrada="teste004"

#-----------------------------------
#===================================

processa ()
{
while read linha
do
controle=`echo $linha | cut -c 1-4`
if [ "$controle" = "<H2>" ]; then
contador=`expr $contador + 1`
particao=`echo "$arquivo_de_saida""$contador"`
elif [ "$controle" = "<H3>" ]; then
particao="/dev/null"
else
echo "$linha" >> "$particao"

fi
done < teste004
}

particao="/dev/null"
contador=0
processa



4. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 01/10/2009 - 19:26h

Cara, na verdade eu não tinha lido tudo ...
então eu vou mandar 2 scripts:

vol.sh e corta_arquivo.sh

O primeiro gera a lista e o segundo realmente é quem corta o arquivo. Só um detalhe, seria legal colocar um move ou um rm, pois todas as vezes que vc executar, os mesmos arquivos ainda estarão lá e ai vai duplicar os registros.

Deixei a linha comentada, mas se quiser, descomenta e cria uma pasta backup ou troca pelo rm.



#vol.sh
#-----------------------------------
# GERA LISTA DO DIRETORIO E
# CHAMA O CORTA ARQUIVO
#-----------------------------------
#

processa0 ()
{
while read lista
do
sh corta_arquivo.sh $lista
#mv "$lista" backup/"$lista" # Move para a pasta backup
done < vol.lista.temp
rm vol.lista.temp
}


ls -l | awk '{ print $NF }' > vol.lista.temp
if [ -d tratados ]; then
processa0
else
mkdir tratados
processa0
fi



5. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 01/10/2009 - 19:28h

Esse aqui é o corta_arquivos atualizado, ele vai jogar seus arquivos numa pasta chamada tratados. .. Fui






# corta_arquivo.sh
#-----------------------------------
# CORTA ARQUIVO
#-----------------------------------
# Preencha as informacoes abaixo

arquivo_de_entrada="$1"

#-----------------------------------
#===================================

processa ()
{
while read linha
do
controle=`echo $linha | cut -c 1-4`
if [ "$controle" = "<H2>" ]; then
nome=`echo "$linha" | sed -e 's/<H2>//g' -e 's/<\/H2>//g' | sed -e 's/ /_/g'`
particao=`echo "tratados/""$nome".txt`
elif [ "$controle" = "<H3>" ]; then
particao="/dev/null"
else
echo "$linha" >> "$particao"

fi
done < "$arquivo_de_entrada"
}

particao="/dev/null"
contador=0
processa



6. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

Lincoln Oliveira de Souza
lincolnsol

(usa Fedora)

Enviado em 02/10/2009 - 01:06h

Muitissimo obrigado pela força ... fez exatamente o q eu queria

Ai brther eu sei q é pedir muito mas tem mais duas coisas que quero pedir:

1° - Como eu faço um loop pra esse script variar o nome do arquivo de entrada? O nome do arquivo de entrada varia de "sounding(01)" até "sounding(500)" em alguns casos. Eu tentei usar o UNTIL mas dá erro pq tem parenteses no nome do arquivo.

2° - Vc poderia explicar melhor cada comando para q eu possa entender o que faz e cada comando dentro do o script?

e como eu faço


7. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 02/10/2009 - 13:50h

Claro que posso ... o intuito é esse mesmo, que vc aprenda e possa ajudar outras pessoas tb.
Bom, primeiro vou explicar uma coisa, eu uso estrutura de funções, que foi como eu comecei a aprender e acho que me ajuda a não me perder ... mas é frescura pura cara, logo, se não quiser ... nem esquenta com isso.

Uma função tem a estrutura abaixo:

nome_da_funcao ()
{
tudo que ela
deve fazer
}

Com isso, ao chamar o nome da função ele vai para este trecho, como se fosse um módulo a parte.
Isto posto, vamos ao script 1:

#vol.sh
#-----------------------------------
#ls -l | awk '{ print $NF }' > vol.lista.temp
#-----------------------------------
"ls -l" => lista todos os arquivos do diretório corrente (vc pode usar o find tb. Aqui vc poderia usar: ls -l sounding*
"awk '{ print $NF }'" => o awk é show de bola cara, mas aqui ele só esta retornando o último elemento do ls, que é o nome do arquivo.
" > vol.lista.temp" => e a saida é pro nosso arquivo de work.

#if [ -d tratados ]; then
#processa0
#else
#mkdir tratados
#processa0
#fi
#-----------------------------------
Essa parte verifica se existe o diretório tratados, se não existir cria e chama o módulo processa0.

#processa0 ()
#{
#while read lista
#do
#-----------------------------------
Aqui um loop que faz tudo até o done

#sh corta_arquivo.sh $lista
#-----------------------------------
Chama o segundo script e passa o nome do arquivo à ser dividido.
#mv "$lista" backup/"$lista" # Move para a pasta backup
#done < vol.lista.temp
#-----------------------------------
Arquivo de entrada para o While
rm vol.lista.temp
}



8. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 02/10/2009 - 14:23h

Dividi o tópico pra não ficar poluido.

Script 2, nesse cara é que está a divisão dos arquivos efetivamente.

# corta_arquivo.sh
#-----------------------------------
#arquivo_de_entrada="$1"
"$1" => recebe o nome de arquivo que o outro script passou.

#processa ()
#{
#while read linha
#do
#controle=`echo $linha | cut -c 1-4`
#-----------------------------------
Leio com o while, o arquivo passado linha a linha e vejo se os primeiros 4 bytes da linha.

#if [ "$controle" = "<H2>" ]; then
#nome=`echo "$linha" | sed -e 's/<H2>//g' -e 's/<\/H2>//g' | sed -e 's/ /_/g'`
particao=`echo "tratados/""$nome".txt`
#-----------------------------------
Se o controle, ou seja, os primeiros 4 bytes forem <H2>, ou seja, o cabeçalho do que voce quer, então eu uso o sed para:
-Substituir <H2> por nada:
"sed -e 's/<H2>//g'"
-Substituir </H2>
"-e 's/<\/H2>//g'"
-Subsituir os espaços por underline.
"sed -e 's/ /_/g'"
E ai formo o nome do arquivo, assim o nome do arquivo permanece o mesmo até encontrar um <H3>.

#elif [ "$controle" = "<H3>" ]; then
#particao="/dev/null"
#-----------------------------------
Se for um <H3> ... é hora de parar de jogar naquele arquivo, então ele só muda o lugar de gravação para /dev/null (vulgo buraco negro), até encontrar outro <H2> que passará o nome de um arquivo válido.

#else
#echo "$linha" >> "$particao"
#-----------------------------------
Se for outra coisa que não H2 ou H3 joga a saida para o arquivo determinado em uma partição, por isso se estiver entre um H2 e um H3 vai para um luga válido, se não é só excluido.

#fi
#done < "$arquivo_de_entrada"
#-----------------------------------
Arquivo de entrada, lembra que você recebeu este nome lá do script 1 via $1.

}

#particao="/dev/null"
#processa
#-----------------------------------
Na verdade o Script começa aqui, então inicia a execução com /dev/null, assim se tiver algum registro antes do primeiro H2 o script sabe pre onde mandar. Ai chama o "processa" pra começar o processamento.

E é isso ai cara ... espero ter ajudado.


9. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

Lincoln Oliveira de Souza
lincolnsol

(usa Fedora)

Enviado em 05/10/2009 - 19:37h

Muito obrigado pela força fdmarp!!!

Mas ainda tenho mais uma duvida.
Seguindo os scripts que vc mostrou,eu "fiz" 3 scripts:

1° (vol.sh) - lista os arquivos do diretorio, transforma os nomes em variaveis e chama o corta_arquivo.sh

2° (corta_arquivo.sh) - lê o arquivo determinado pelo vol.sh, divide o arquivo onde foi determinado e chama orenomeia.sh

3° (renomeia.sh) - renomeia os arquivos de saida para o formato q eu presiso.
--------------------------------------------------------------------
PROBLEMA:
Mas brother as scripts não estão funcionando ... naum seibem pq, na realo procedimento acontece, porem no fim do processo os arquivos de saida estão ficando vazios

vc poderia dar uma lida nos scripts pra ver onde eu estou errando ???

segue abaixo os 3 scripts q estou usando e link para um arquivo de teste:
http://www.4shared.com/file/132893608/232e19eb/sounding_30_.html
--------------------------------------------------------------------
vol.sh
cd /home/Lincoln/Dados/Brutos/Alta\ Floresta/
ls -l sounding* | awk '{ print $NF }' > vol.lista.temp
processa0 ()
{
while read lista
do
cd /home/Lincoln/Scripts/
sh corta_arquivo.sh $lista
sleep 10 #coloquei esse sleep pra ver se dava tempo dos outros script terminarem antes dele começar denovo
done < vol.lista.temp
cd /home/Lincoln/Dados/Brutos/Alta\ Floresta/
#rm vol.lista.temp
}
processa0
--------------------------------------------------------------------
corta_arquivo.sh
arquivo_de_entrada="$1"
cd /home/Lincoln/Dados/Brutos/Alta\ Floresta/
processa ()
{
while read linha
do
controle=`echo $linha | cut -c 1-4`
if [ "$controle" = "<H2>" ]; then
nome=`echo "$linha" | sed -e 's/<H2>//g' -e 's/<\/H2>//g' | sed -e 's/ /_/g'`
particao=`echo "/home/Lincoln/Dados/Temp/""$nome".txt`
elif [ "$controle" = "<H3>" ]; then
particao="/dev/null"
else
echo "$linha" >> "$particao"
fi
cd /home/Lincoln/Scripts/
sh renomeia.sh
sleep 10
done < "$arquivo_de_entrada"
}
particao="/dev/null"
processa
--------------------------------------------------------------------
renomeia.sh
cd /home/Lincoln/Dados/Temp/
nome_velho=$(ls)
estacao=$(ls | cut -d"_" -f1 )
nome=$(ls | cut -d"_" -f3)
nome2=$(ls | cut -d"_" -f4)
ano=$(ls | cut -d"_" -f11 | cut -d"." -f1)
mes=$(ls | cut -d"_" -f10)
dia=$(ls | cut -d"_" -f9)
if [ $mes == Dec ]; then
mes=$((12))
fi
if [ $mes == Nov ]; then
mes=$((11))
fi
if [ $mes == Out ]; then
mes=$((10))
fi
if [ $mes == Sep ]; then
mes=$((09))
fi
if [ $mes == Aug ]; then
mes=$((08))
fi
if [ $mes == Jul ]; then
mes=$((07))
fi
if [ $mes == jun ]; then
mes=$((06))
fi
if [ $mes == May ]; then
mes=$((05))
fi
if [ $mes == Apr ]; then
mes=$((04))
fi
if [ $mes == Mar ]; then
mes=$((03))
fi
if [ $mes == Feb ]; then
mes=$((02))
fi
if [ $mes == Jan ]; then
mes=$((01))
fi
nome_novo=$(echo $nome $nome2 $ano $mes $dia.txt)
mv "$nome_velho" "$(echo $nome_velho | sed "s/$nome_velho/$nome_novo/")"
mv $nome_novo /home/Lincoln/Dados/Tratados/Alta\ Floresta/
cd /home/Lincoln/Dados/Tratados/Alta\ Floresta/
nome_novo2=$(ls)
for i in *' '* ; do mv "$i" "${i// /_}" ; done # esse comando eu não entendi direito mas sei q funcionou qundo eu testei
nome_novo2=$(ls)
echo $nome_novo2 Pronto !!!
--------------------------------------------------------------------



10. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 07/10/2009 - 15:35h

Seguem os 2 scripts corrigidos.

O terceiro estou verificando ...

Dá algum erro específico?

================================================
#vol.sh
#------------------------------------------------------
cd /home/Lincoln/Dados/Brutos/Alta\ Floresta/
ls -l sounding* | awk '{ print $NF }' > vol.lista.temp
processa0 ()
{
while read lista
do
cd /home/Lincoln/Scripts/
sh corta_arquivo.sh $lista
done < vol.lista.temp
cd /home/Lincoln/Scripts/
sh renomeia.sh
}
processa0

#corta_arquivo.sh
#------------------------------------------------------
arquivo_de_entrada="$1"
cd /home/Lincoln/Dados/Brutos/Alta\ Floresta/
processa ()
{
while read linha
do
controle=`echo $linha | sed -e 's/<\/PRE>//g' | cut -c 1-4`
if [ "$controle" = "<H2>" ]; then
nome=`echo "$linha" | sed -e 's/<H2>//g' -e 's/<\/H2>//g' | sed -e 's/ /_/g'`
particao=`echo "/home/Lincoln/Dados/Temp/""$nome".txt`
elif [ "$controle" = "<H3>" ]; then
particao="/dev/null"
else
echo "$linha" >> "$particao"
fi
done < "$arquivo_de_entrada"
}
particao="/dev/null"
processa



11. Re: Filtrar um arquivo e criar outro [RESOLVIDO]

DAVISON MARCEL PASQUALINI
fdmarp

(usa Debian)

Enviado em 07/10/2009 - 19:12h

Agora vai ein ... tentei não mexer muito na sua estrutura ...
Coloquei 2 tipos de data pq vi que vc usou Dec (December) mas usou Out (Outubro) então esse vale pro portugues e ingles tb.

Certo meu amigo ... Quero ver esse tópico fechado ein ... rsss

Brincadeira, quero é que de certo!


=================
#renomeia.sh
cd /home/Lincoln/Dados/Temp/
ls | while read nome_velho; do
estacao=`echo $nome_velho | cut -d"_" -f1 `
nome=`echo $nome_velho | cut -d"_" -f3`
nome2=`echo $nome_velho | cut -d"_" -f4`
ano=`echo $nome_velho | cut -d"_" -f11 | cut -d"." -f1`
mes=`echo $nome_velho | cut -d"_" -f10`
dia=`echo $nome_velho | cut -d"_" -f9`
case "$mes" in
"Dec" | "Dez" )
mes="12" ;;
"Nov" )
mes="11" ;;
"Oct" | "Out" )
mes="10" ;;
"Sep" | "Set" )
mes="09" ;;
"Aug" | "Ago" )
mes="08" ;;
"Jul" )
mes="07" ;;
"Jun" )
mes="06" ;;
"May" | "Mai" )
mes="05" ;;
"Apr" | "Abr")
mes="04" ;;
"Mar" )
mes="03" ;;
"Feb" | "Fev" )
mes="02" ;;
"Jan" )
mes="01" ;;
* )
mes="$mes";;
esac

nome_novo=`echo $nome $nome2 $ano $mes $dia.txt | sed -e 's/ /_/g'`
mv "$nome_velho" /home/Lincoln/Dados/Tratados/Alta\ Floresta/"$nome_novo"
echo $nome_novo Pronto !!!
done







Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts