Forza le nuove linee con la stampa di caratteri jolly di gatto


9

Voglio usare cat con caratteri jolly in bash per stampare più piccoli file (ogni file è una frase) sullo standard output. Tuttavia, i contenuti del file separato non sono separati da una nuova riga, cosa che mi piacerebbe per facilità di lettura.

Come posso aggiungere un delimitatore di file di qualche tipo a questo comando?

Risposte:


12

Definire una funzione di shell che restituisce la fine della riga dopo ogni file e usarla al posto di cat:

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

allora puoi usare endlcat *.

Il forciclo scorre su tutti gli argomenti forniti ( $@) che sono già sfuggiti alla shell quando si utilizzano caratteri jolly come *. Il --è necessario per non soffocare i nomi di file che iniziano con un trattino. Finalmente echoesce una nuova riga.


Sembra piuttosto ovvio usare l'iterazione con il senno di poi! Pensavo che potesse esserci stata una bandiera nel gatto, ma funziona anche! Grazie.
lennyklb,

Non hai bisogno del in "$@"- è implicito.
l0b0

4
essere espliciti fa bene alla leggibilità.
Cas

5

Basta usare un ciclo anziché semplice cat:

for file in /path/to/targetdir/*; do
    echo "-------- $file -------"
    cat "$file" 
done

Funziona come la risposta accettata, ma quella ha avuto anche il passaggio successivo alla riga di comando, quindi ho accettato l'altra.
lennyklb,

3

Se si desidera il nome del file tra i file, utilizzare tail:

tail -n +1 ./*

(Nel caso in cui si desideri tacinvece cat, alcune tailimplementazioni hanno l' -ropzione per tacfunzioni equivalenti )


3

Questo funzionerà:

sed '' -- *

Non è necessario alcun loop di shell o altro, e questo seguirà sempre l'output di un file con una \newline - tranne forse l'ultimo.

In caso contrario, se si desidera che venga emessa una riga vuota tra l'output di ciascun file, ciò potrebbe funzionare:

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

Ciò seguirà sempre l'output di un file con una \newline e una riga vuota aggiuntiva .

Puoi chiamarlo come:

bpaste *

@cuonglm: l'operazione richiede una nuova riga tra i file. questo assicura una nuova riga tra i file.
Mikeserv,

@cuonglm - dovresti riprovare. for n in 1 2 3; do printf "$n" >"$n"; done; sed '' -- [123]
Mikeserv,

@cuonglm - qualcuno seddeve sempre stampare una \newline prima che stampi qualcos'altro, tuttavia l'ultima riga dell'ultimo file potrebbe non essere \naggiunta a una ewline. potrei giurare di aver già risposto a questa domanda.
Mikeserv,

@cuonglm - non capisco cosa intendi. quel pezzetto di conchiglia che ti ho appena dato delle stampe 1\n2\n3. Funziona. lo fa sempre. cosa stampa per te?
Mikeserv,

1
@DennisWilliamson: l'utilizzo \nin RHS non è standard. È possibile utilizzare sed -e '$G'.
cuonglm,

2

Simile alla risposta di @terdon , se preferisci vedere anche il nome del file in futuro, puoi usare il headcomando:

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

==> file_2 <==
file 2 content

==> file_3 <==
file 3 content

headper impostazione predefinita sono le prime 10 righe, quindi usarlo senza opzioni di comando per il tuo caso (una frase per file) va benissimo. Altrimenti, hai bisogno -n Xdell'opzione.


2

Un altro modo: utilizzare grep -hsemplicemente per cercare la stringa vuota in ciascun file. Questo corrisponderà a tutte le righe, indipendentemente da quante o se terminate da newline o meno. i risultati grep sono sempre terminati a fine riga. L' -hopzione sopprime il prefisso di ogni riga di output con il nome file da cui proviene:

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

Oppure potresti usare GNU pastein -smodalità erial con newline come delimitatore:

$ paste -s -d '\n' -- *
a
b
B
c
$ 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.