Autor Tópico: loop com cat  (Lida 3461 vezes)

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
loop com cat
« Online: 15 de Fevereiro de 2012, 20:37 »
Pessoal, tenho file1, ..., filen na pasta. São arquivos de texto.

Quero colocar o conteúdo deles em um só, como se fosse colado um após o outro.

Tentei usar o seguinte:
Código: [Selecionar]
cat file* >> saidamas não deu certo, pois ficou assim:
file1
file1 + file2
...
file1 + ... + filen
ou seja, ele fez uma série e não uma sequência, isto é, o conteúdo dos arquivos ficaram repetidos.

Como fazer? Não queria ter que fazer n vezes
Código: [Selecionar]
cat file1 >> saida && file2 >> saida


Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: loop com cat
« Resposta #1 Online: 15 de Fevereiro de 2012, 21:38 »
Use um laço
Código: [Selecionar]
for i in file*; do
   [[ -f $i ]] || continue
   cat "$i" >> saida
done

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: loop com cat
« Resposta #2 Online: 15 de Fevereiro de 2012, 22:25 »
Use um laço
Código: [Selecionar]
for i in file*; do
   [[ -f $i ]] || continue
   cat "$i" >> saida
done

Opa, valeu hein! Posso digitar isso tudo no terminal, dando <enter> só no final, uma vez só?
Ou isso só funciona com um file.sh?

|| é um OU lógico, não é? Então, o que faz o [[ -f $i ]] ?

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: loop com cat
« Resposta #3 Online: 15 de Fevereiro de 2012, 22:56 »
Um teste: http://aurelio.net/shell/canivete/#test

Olhando de novo o exemplo, eu vejo que o problema são os arquivos, então use
Código: [Selecionar]
for i in file*; do
   [[ -f $i ]] || continue
   cat "$i" >> saida && echo -n "\n" >> saida
done

E pode copiar e colar, direto... mas certifique-se que está no diretório correto.

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: loop com cat
« Resposta #4 Online: 15 de Fevereiro de 2012, 23:05 »
Certo, para cada arquivo, ele testa se o arquivo existe. se sim, faz o cat. só não entendi o porque de usar o || continue. seria para garantir que se o arquivo não existe, então ele tenta com o próximo? mas esse laço não é exatamente para o file*, ou seja, sempre terá o arquivo. A menos que não tenha nenhum arquivo file?

Outra coisa, para que serve a opção -n do echo? sei que o \n é para inserir newline, mas o -n como opção?

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: loop com cat
« Resposta #5 Online: 15 de Fevereiro de 2012, 23:17 »
Se não for um arquivo comum ele pula pro próximo do glob. Com o -n o echo não insere o terminador que indica nova linha. Se você usar vai intender:
Código: [Selecionar]
echo "inicio" > file1 && echo "meio" > file2 && echo "fim" > file3
cat file*
Código: [Selecionar]
echo -n "inicio" > file1 && echo -n "meio" > file2 && echo -n "fim" > file3
cat file*

Obs: teste, teste e teste!

Offline sigur

  • Usuário Ubuntu
  • *
  • Mensagens: 1.176
    • Ver perfil
Re: loop com cat
« Resposta #6 Online: 15 de Fevereiro de 2012, 23:25 »
haha, entendi. bacana!
mas pelo que me parece, você usa -n para não ter nova linha, mas depois insere o \n na raça? porque não deixa então sem o -n e sem o \n? vou fazer alguns outros testes. valeu!

Offline irtigor

  • Equipe Ubuntu
  • Usuário Ubuntu
  • *****
  • Mensagens: 4.344
  • Delete, delete, delete!
    • Ver perfil
Re: loop com cat
« Resposta #7 Online: 15 de Fevereiro de 2012, 23:33 »
Porque o arquivo não tem o terminador... veja a diferença:

Código: [Selecionar]
rm saida &> /dev/null
echo -n "inicio" > file1 && echo -n "meio" > file2 && echo -n "fim" > file3
for i in file*; do
   [[ -f $i ]] || continue
   cat "$i" >> saida && echo -n "\n" >> saida
done
cat saida

Código: [Selecionar]
rm saida &> /dev/null
echo -n "inicio" > file1 && echo -n "meio" > file2 && echo -n "fim" > file3
for i in file*; do
   [[ -f $i ]] || continue
   cat "$i" >> saida && echo "\n" >> saida
done
cat saida

São arquivos feitos no windows? Compensa mais converter com o dos2unix (pra ter os terminadores corretos) e depois usar o cat com glob normal.

---
Não sei se a minha sugestão anterior vai funcionar, se os arquivos tiverem mais de uma linha, porque a nova linha só é inserida no final do arquivo.
« Última modificação: 15 de Fevereiro de 2012, 23:58 por irtigor »