Concatenando arquivos e inserir nova linha entre arquivos

Respostas:

121

Você pode fazer:

for f in *.txt; do (cat "${f}"; echo) >> finalfile.txt; done

Verifique se o arquivo finalfile.txtnão existe antes de executar o comando acima.

Se você tem permissão para usar, awkpode:

awk 'FNR==1{print ""}1' *.txt > finalfile.txt
codaddict
fonte
10
AWK '{print $0}' *.txt
timger
7
Isso tem a falha distinta de que haverá linhas vazias no final (da primeira alternativa) ou no início (segunda alternativa). awk 'FNR==1 && NR > 1 ...'Porém, você pode se proteger facilmente disso.
Tripleee
5
Se você colocar >finalfile.txtapós, donepoderá substituir em vez de anexar, o que removerá o requisito para garantir que o arquivo esteja ausente ou vazio antes do loop.
Tripleee
53

Se você tiver poucos arquivos suficientes para listar cada um deles, poderá usar a substituição de processos no Bash, inserindo uma nova linha entre cada par de arquivos:

cat File1.txt <(echo) File2.txt <(echo) File3.txt > finalfile.txt
Robert Tupelo-Schneck
fonte
1
Lindo! Obrigado.
Bob Kocisko
Isso funcionou muito bem para meus certificados Letsencrypt para criar arquivos .pem.
leeman24
35

Se fosse eu, usaria o sed:

sed -e '$s/$/\n/' -s *.txt > finalfile.txt

Nesse padrão sed, $ tem dois significados: primeiro, corresponde apenas ao número da última linha (como um intervalo de linhas para aplicar um padrão) e, em segundo lugar, ao final da linha no padrão de substituição.

Se a sua versão do sed não tiver -s(processar arquivos de entrada separadamente), você poderá fazer tudo isso como um loop:

for f in *.txt ; do sed -e '$s/$/\n/' $f ; done > finalfile.txt
Flexo
fonte
3
Ou no GNU sed:sed -s '$G' *.txt > finalfile.txt
Ruud Helderman
Apenas um fluxo! essa deve ser a resposta aceita!
Yassine ElBadaoui
cuidado pessoal, acabei de travar meu PC porque usei findno lugar do *.txt, o que significava que o arquivo foi anexado a ele!
Xerus
11

Você pode fazer isso usando, xargsse quiser, mas a ideia principal ainda é a mesma:

find *.txt | xargs -I{} sh -c "cat {}; echo ''" > finalfile.txt
Nick Roz
fonte
1
Obrigado. Acho xargsmuito mais fácil usar do que loops no bash.
precisa saber é o seguinte
9

Isso funciona no Bash:

for f in *.txt; do cat $f; echo; done

Ao contrário das respostas com >>(anexar), a saída desse comando pode ser canalizada para outros programas.

Exemplos:

  • for f in File*.txt; do cat $f; echo; done > finalfile.txt
  • (for ... done) > finalfile.txt (parens são opcionais)
  • for ... done | less (canalizando para menos)
  • for ... done | head -n -1 (isso retira a linha em branco à direita)
user3780389
fonte
7

Foi assim que fiz no OsX 10.10.3

for f in *.txt; do (cat $f; echo '') >> fullData.txt; done

desde que o simples comando 'eco' sem parâmetros tenha terminado em nenhuma nova linha inserida.

lbrutti
fonte
Isso coloca a string no final do arquivo; como faço para inseri-lo entre cada arquivo?
Onassar
3

Em python, isso concatena com linhas em branco entre arquivos (o que ,suprime a adição de uma linha em branco à direita):

print '\n'.join(open(f).read() for f in filenames),

Aqui está o feio one-liner python que pode ser chamado a partir do shell e imprime a saída em um arquivo:

python -c "from sys import argv; print '\n'.join(open(f).read() for f in argv[1:])," File*.txt > finalfile.txt
user3780389
fonte