Force novas linhas com impressão de caractere curinga de gato

8

Eu quero usar o cat com curingas no bash para imprimir vários arquivos pequenos (cada arquivo é uma frase) para a saída padrão. No entanto, o conteúdo do arquivo separado não é separado por uma nova linha, o que eu gostaria de facilitar a leitura.

Como posso adicionar um arquivo delimitador de algum tipo a este comando?

    
por Lennart Kloppenburg 14.10.2015 / 16:24

6 respostas

12

Defina uma função shell que produza um final de linha após cada arquivo e use-a em vez de cat :

endlcat() {
  for file in "$@"; do
    cat -- "$file"
    echo
  done
}

então você pode usar endlcat * .

Ofor ciclo% loop sobre todos os argumentos apresentados ( $@ ) que já estão escaparam pelo shell quando você usar curingas como * . O -- é necessário para não engasgar com nomes de arquivos que começam com um traço. Finalmente, o echo gera uma nova linha.

    
por 14.10.2015 / 16:39
5

Use apenas um loop em vez de simples cat :

for file in /path/to/targetdir/*; do
    echo "-------- $file -------"
    cat "$file" 
done
    
por 14.10.2015 / 16:37
3

Se você quiser o nome do arquivo entre os arquivos, use tail :

tail -n +1 ./*

(Caso você queira tac em vez de cat , alguma tail implementação tem -r opção para% equivalentetac funcional)

    
por 14.10.2015 / 18:32
2

Semelhante à resposta do @terdon , se você preferir ver o nome do arquivo no futuro também , você pode usar o comando head :

$ head *file*
==> file_1 <==
file 1 content

==> file_2 <==
file 2 content

==> file_3 <==
file 3 content

head é padronizado para as primeiras 10 linhas, então usá-lo sem opções de comando para o seu caso (uma frase por arquivo) está perfeitamente bem. Caso contrário, você precisa da opção -n X .

    
por 14.10.2015 / 17:56
2

Isso funcionará:

sed '' -- *

Você não precisa de nenhum loop de shell ou de outra forma, e isso sempre seguirá a saída de um arquivo com \n ewline - exceto talvez o último.

Caso contrário, se você quiser que uma linha blank seja enviada entre a saída de cada arquivo, isso pode funcionar:

bpaste(){
    eval "paste -'sd\n' -- $(x=0;for f do printf "\"\${$((x+=1))}\" - ";done)"
}   </dev/null

Isso sempre seguirá a saída de um arquivo com um \n ewline e uma linha adicional em branco .

Você pode chamá-lo assim:

bpaste *
    
por 14.10.2015 / 18:36
2

Outra maneira - use grep -h para simplesmente procurar a string vazia em cada arquivo. Isto irá corresponder a todas as linhas, independentemente de quantas ou se novas linhas terminadas ou não. Os resultados do grep são sempre terminados por nova linha. A opção -h suprime o prefixo de cada linha de saída com o nome de arquivo do qual ela veio:

$ printf 'a' > a
$ printf 'b\nB' > b
$ printf 'c\n' > c
$ ls
a  b  c
$ cat -- *
ab
Bc
$ grep -h '' *
a
b
B
c
$ 

Ou você pode usar o modo GNU paste no modo -s com nova linha como o delimitador:

$ paste -s -d '\n' -- *
a
b
B
c
$ 
    
por 15.10.2015 / 03:45