Como se pode juntar arquivos com separação de dados no bash?

7

Então, pode-se facilmente juntar arquivos no bash com o cat:

cat *.txt > all.txt

Mas e se alguém quiser inserir algo entre os arquivos de entrada, como por exemplo um avanço de linha?

Roger Ertesvag
fonte

Respostas:

7

Requer GNU sed:

sed -s '$G' *.txt > all.txt

acrescentar uma linha de 8 traços e uma nova linha após cada arquivo

sed -s '$a--------' *.txt

Você pode usar seu sed '$ d' com isso

Compare com estes:

Inserir uma linha de traços antes de cada arquivo:

sed -s '1i--------' *.txt

Faça o mesmo, mas sem uma nova linha após os traços:

sed -s '1s/^/--------/' *.txt

Coloque uma linha de traços no final da última linha de cada arquivo:

sed -s '$s/$/--------/' *.txt

Envolva cada arquivo com chaves:

sed -s -e '1i{' -e '$a}' *.txt
Dennis Williamson
fonte
Solução elegante para inserir alimentação de linha, fiz uma pequena modificação para ter apenas os avanços entre os arquivos originais não no final: sed -s '$ G' * .txt | sed '$ d'> all.txt Mas este método também pode ser usado para inserir outros dados, para estar mais de acordo com a questão geral?
Roger Ertesvag
@Roger: sed -s '$a--------' *.txtacrescentaria uma linha de 8 traços e uma nova linha após cada arquivo. Você pode usar o seu sed '$d'com isso. Compare a estes: sed -s '1i--------' *.txt, sed -s '1s/^/--------/' *.txt, sed -s '$s/$/--------/' *.txtesed -s -e '1i{' -e '$a}' *.txt
Dennis Williamson
Você poderia adicionar essas opções à resposta?
Roger Ertesvag
6

Como um one-liner com subshells:

( for i in *.txt ; do cat $i ; echo 'separator here' ; done ) >all.txt

Veja o que o subshell executa dividido em linhas de estilo de script:

para i em * .txt
Faz
gato $ i
eco 'separador vai aqui' 
feito

Neste exemplo, o separador age como um rodapé; adicione um cabeçalho adicionando outro echoantes do cat.

gorila
fonte
2
Não há necessidade para o subshell, e você deve usar aspas duplas em torno da expansão da variável para proteger qualquer espaço em branco nos nomes dos arquivos. for i in *.txt; do cat "$i"; echo 'stuff'; done > all.txt
Chris Johnsen
Isso pode ser modificado para não inserir o separador no final do arquivo de resultado, apenas entre os arquivos originais?
Roger Ertesvag
@ Roger:files=(*.txt); indices=(${!files[@]}); for i in ${indices[@]}; do cat "${files[i]}"; if [[ $i != ${indices[@]: -1} ]]; then echo "separator"; fi; done > all.txt
Dennis Williamson
1
catWithSep() { sep="$1"; shift; first=''; for f; do test -n "$first" && echo "$sep"; cat "$f"; first=no; done; }; catWithSep separator *.txt
Chris Johnsen
@ Chris: bom um!
Dennis Williamson