Afficher les lignes vides par la commande cat


11

J'ai une liste de files.txt, ci-dessous:

-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  

Production:

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

Comment obtenir la sortie comme ci-dessous:

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

Besoin de conseils.


Les fichiers contiennent-ils jamais plus d'une ligne?
roaima

Non, seulement 1 ligne
Fewong

1
Euh, quand vous avez écrit [Blank], vouliez-vous dire ces 7 caractères ou aviez-vous l'intention d'indiquer une ligne vide?
roaima

1
En n'utilisant pas de chat. Ne vous contraignez pas.
ctrl-alt-delor

Réponses:


20

catne peut pas sortir des données qui n'existent pas dans les fichiers. Si un fichier est vide, il n'a même pas de caractère de nouvelle ligne pour fournir une ligne vide en sortie.

Vous pouvez vous assurer que les fichiers contiennent au moins un seul caractère de nouvelle ligne.

Voici comment vous utilisez GNU awkpour vous assurer que (cela modifie les fichiers vides):

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

Le ENDFILEbloc sera exécuté après avoir fini de lire l'un des fichiers. Si FNRest zéro, nous n'avons jamais vu de lignes dans le fichier, nous y insérons donc une seule nouvelle ligne. Le script continue ensuite avec le fichier suivant.

Vous pouvez ensuite utiliser catcomme vous l'avez fait dans la question.


Alternativement, sans changer les fichiers, utilisez GNU awk au lieu de cat :

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

Cela fait le même type de détection de fichiers vides que ci-dessus, mais imprime la nouvelle ligne sur la sortie standard plutôt que sur le fichier. Le 1à la fin pourrait être remplacé par { print }et entraînera la sortie de toutes les données dans les fichiers non vides.


Alternativement, une boucle shell (devrait fonctionner dans n'importe quel shell POSIX):

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

Le -stest sera vrai si le fichier existe et a une taille supérieure à zéro.


Si vous souhaitez que la chaîne littérale [Blank]soit sortie pour les fichiers vides, insérez simplement cette chaîne devant \ndans les appels à printfci-dessus (cela fonctionnera également dans le awkcode).


2
@Fewong Good! Si cela résout votre problème, pensez à accepter la réponse .
Kusalananda

@Fewong: Ou acceptez une autre réponse qui vous aide encore mieux - c'est une bonne pratique de donner une chance à chaque fuseau horaire, donc rien ne presse.
MSalters

@Fewong Certainement pas pressé. Stephané a également écrit une solution courte et compacte, qui semble prometteuse.
Kusalananda

@Kusalananda, merci et j'ai testé que cela fonctionnait.
Fewong

16

Avec perl

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

Ce qui ajoute un caractère de nouvelle ligne s'il est manquant à la fin, produirait donc une ligne vide pour les fichiers vides, mais ajouterait également une nouvelle ligne pour les fichiers non vides qui en manquent (et finiraient par être concaténés sur une seule ligne avec cat).


belle suggestion
erTugRul

13

(Ce n'est pas exactement ce que vous demandez, mais :) Dans ce type de situations, je préfère utiliser 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 <==

Normalement, c'est ce que vous voulez. Sinon, c'est facile à sedfaire plus tard


12

Avec xargset grepvous pouvez essayer quelque chose comme:

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

4
Peut-être pas la solution la plus rapide (bifurquer un shell pour chaque fichier), mais une seule jusqu'à présent qui fonctionnera réellement si vous avez des millions de ces fichiers dans le répertoire actuel (sans utiliser les extensions de shell et atteindre la limite ARGV).
Matija Nalis

1
@MatijaNalis: Très vrai! Mais vous ne vous souciez vraiment pas de 5 fichiers.
FloHimself

6

En supposant que [Blank]vous entendiez par là des lignes blanches littérales, cela devrait fonctionner:

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

6

Vous pouvez tester chaque fichier pour voir s'il est de longueur nulle avant d'essayer d'afficher son contenu:

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

J'ai utilisé awk 1 "$f"au lieu de cat "$f"parce que awkgarantit de terminer la sortie d'un fichier avec une nouvelle ligne.

Dans votre question, si vous vouliez que ce [blank]ne soit pas un littéral, mais simplement une ligne vierge, vous pouvez l'implémenter en utilisant le code ci-dessus et en le supprimant '[Blank]'à la fin de l' echoinstruction.


5

Je suppose que vos fichiers 26_SumActive.txt et 28_SumActive.txt sont vides et que vous avez besoin de lignes vides pour afficher leur contenu

Pour cela, vous pouvez simplement parcourir votre liste de fichiers et lire leur contenu, et si le fichier est vide, faites écho à la ligne vierge.

[ -s FILE ] Vrai si FILE existe et a une taille supérieure à zéro.

$ 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
Ou if [ -s $i ]; then cat $i; else echo -e ""; fi;. Toujours +1 pour un test simple utilisant uniquement la fonctionnalité shell standard.
MSalters

2
Ou tout simplement cat "$i"; test -s "$i" || echo- pas besoin de ces drapeaux lourds ifou non portables echo.
Toby Speight

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

- permettra au chat de lire à partir de l'entrée standard.

Ainsi, après avoir affiché le contenu de vos fichiers, cat attendra votre entrée. Vous pouvez faire votre entrée souhaitée, en appuyant sur Entrée pour les blancs littéraux ou [Blanc] si c'est ce que vous voulez. Après chaque entrée, appuyez sur Entrée, une fois toutes les entrées effectuées, appuyez sur ^ D (Ctrl + D) et vous avez terminé.

PS: Pour chaque entrée, vous obtiendrez une sortie respective.

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

Avec cela, vous pouvez mettre des blancs ou quelque chose d'autre que vous voulez, entre deux séquences de sorties.


Sur cette base, vous pourriez tout aussi bien proposer catune solution et permettre à l'OP de répondre à vos attentes.
roaima
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.