Visualizza righe vuote con il comando cat


11

Ho un elenco di files.txt, di seguito:

-rw-rw-r-- 1 root dev 11 May 16 12:18 20_SumActive.txt  
-rw-rw-r-- 1 root dev 11 May 16 12:18 22_SumActive.txt  
-rw-rw-r-- 1 root dev  7 May 16 12:18 24_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 26_SumActive.txt  
-rw-rw-r-- 1 root dev  0 May 16 12:18 28_SumActive.txt  

Produzione:

kpgmeddev01> cat 2[0-8]_SumActive.txt   
Sum: 47760  
Sum: 72000  
Sum: 0

Come ottenere l'output come di seguito:

Sum: 47760  
Sum: 72000  
Sum: 0  
[Blank]  
[Blank]  

Hai bisogno di una guida.


I file contengono mai più di una riga?
roaima,

No, solo 1 riga
Fewong

1
Uh, quando hai scritto [Blank]intendevi quei 7 caratteri o avevi intenzione di indicare una riga vuota?
roaima,

1
Non usando il gatto. Non costringere te stesso.
ctrl-alt-delor,

Risposte:


20

catimpossibile generare dati che non esistono nei file. Se un file è vuoto, non ha nemmeno un carattere di nuova riga per fornire una riga vuota come output.

Puoi assicurarti che i file contengano almeno un singolo carattere di nuova riga.

Questo è il modo in cui usi GNU awkper assicurarti che (questo modifica i file vuoti):

awk 'ENDFILE { if (FNR == 0) printf("\n") >>FILENAME }' 2[0-8]_SumActive.txt   

Il ENDFILEblocco verrà eseguito al termine della lettura di uno qualsiasi dei file. Se FNRè zero, non abbiamo mai visto alcuna riga nel file, quindi inseriamo una sola nuova riga in esso. Lo script continua quindi con il file successivo.

È quindi possibile utilizzare catcome nella domanda.


In alternativa, senza modificare i file, utilizzare GNU awk invece di cat :

awk 'ENDFILE { if (FNR == 0) printf("\n") } 1' 2[0-8]_SumActive.txt

Questo fa lo stesso tipo di rilevamento di file vuoti come sopra, ma stampa la nuova riga sull'output standard anziché sul file. Alla 1fine potrebbe essere sostituito { print }e causerà la trasmissione di tutti i dati nei file non vuoti.


In alternativa, un loop di shell (dovrebbe funzionare in qualsiasi shell POSIX):

for name in ./2[0-8]_SumActive.txt; do
    if [ -s "$name" ]; then
        cat "$name"
    else
        printf '\n'
    fi
done

Il -stest sarà vero se il file esiste e ha una dimensione maggiore di zero.


Se si desidera che la stringa letterale [Blank]venga emessa per file vuoti, è sufficiente inserire quella stringa davanti \nnelle chiamate printfsopra (funzionerà anche nel awkcodice).


2
@Fewong Good! Se questo risolve il tuo problema, considera di accettare la risposta .
Kusalananda

@Fewong: Oppure accetta un'altra risposta che ti aiuta ancora meglio: è buona norma dare una possibilità a ogni fuso orario, quindi non c'è fretta.
MSalters,

@Fewong Sicuramente senza fretta. Stephané ha anche scritto una soluzione breve e compatta, che sembra promettente.
Kusalananda

@Kusalananda, grazie e ho provato che ha funzionato.
Fewong

16

Con perl

perl -0777 -pe 's/\n?\z/\n/' 2[0-8]_SumActive.txt

Il che aggiunge un carattere di nuova riga se manca alla fine, quindi genererebbe una riga vuota per i file vuoti, ma aggiungerebbe anche una nuova riga per i file non vuoti che mancano quelli (e finirebbe per essere concatenato su una singola riga con cat).


bel suggerimento
erTugRul

13

(Questo non è esattamente ciò che chiedi, ma :) In questo tipo di situazioni preferisco usare head

$ head -z 2[0-8]_SumActive.txt
==> 21_SumActive.txt <==
Sum: 47760  
Sum: 72000  
Sum: 0  

==> 22_SumActive.txt <==

==> 25_SumActive.txt <==

==> 28_SumActive.txt <==

Normalmente questo è quello che vuoi. Altrimenti è facile seddopo


12

Con xargse greppotresti provare qualcosa del tipo:

$>ls | xargs -n1 sh -c 'grep "" $0 || echo "[Blank]"'
Sum: 47760
Sum: 72000
Sum: 0
[Blank]
[Blank]

4
Forse non è la soluzione più veloce (il fork di una shell per ogni file), ma solo una finora che funzionerà effettivamente se ci sono milioni di tali file nella directory corrente (non usando espansioni della shell e colpendo il limite ARGV).
Matija Nalis,

1
@MatijaNalis: Molto vero! Ma davvero non ti importerebbe per 5 file.
FloHimself

6

Supponendo che [Blank]intendi letteralmente righe vuote, questo dovrebbe funzionare:

paste -s 2[0-8]_SumActive.txt

6

Puoi testare ogni file per vedere se ha lunghezza zero prima di provare a visualizzarne il contenuto:

for f in 2[0-8]_SumActive.txt;
do
    [[ -s "$f" ]] && awk 1 "$f" || echo '[Blank]'
done

Ho usato awk 1 "$f"invece cat "$f"perché perché awkgarantisce la fine dell'output di un file con una nuova riga.

Nella tua domanda, se intendi che [blank]non dovrebbe essere un valore letterale, ma solo una riga vuota, puoi implementarlo utilizzando il codice sopra e rimuovendolo '[Blank]'dalla fine echodell'istruzione.


5

Presumo che i tuoi file 26_SumActive.txt e 28_SumActive.txt siano vuoti e siano necessarie righe vuote per visualizzare il loro contenuto

Per questo, puoi semplicemente scorrere l'elenco dei file e catalogarne il contenuto, e se il file è vuoto, fai eco a una riga vuota.

[ -s FILE ] Vero se FILE esiste e ha dimensioni maggiori di zero.

$ for i in $(ls 2[0-8]_SumActive.txt) ; do  cat $i;  if [ ! -s $i ]; then echo -e ""; fi; done
Sum: 47760  
Sum: 72000  
Sum: 0  
[ Blank Line]
[ Blank Line ]

1
Or if [ -s $i ]; then cat $i; else echo -e ""; fi;. Ancora +1 per un semplice test usando solo la funzionalità shell standard.
Sali

2
O semplicemente cat "$i"; test -s "$i" || echo- non c'è bisogno di quelle bandiere ingombranti ifo non portatili echo.
Toby Speight,

1
cat 2[0-8]_SumActive.txt -

dove - consentirà a cat di leggere dall'input standard.

Quindi, dopo aver visualizzato il contenuto dei tuoi file, cat attenderà il tuo input. È possibile effettuare l'input desiderato, premendo invio per gli spazi vuoti letterali o [Vuoto] se è quello che si desidera. Dopo ogni input premere invio, una volta effettuati tutti gli input premere ^ D (Ctrl + D) e il gioco è fatto.

PS: per ogni input otterrai l'output corrispondente.

cat 2[0-8]_SumActive.txt - 4[0-8]_SumActive.txt

Con questo sei in grado di mettere spazi vuoti o qualcos'altro che vuoi, tra due sequenze di output.


Su questa base potresti anche offrire catuna soluzione e consentire al PO quello che vogliono.
roaima,
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.