web-dev-qa-db-fra.com

Comment vérifier qu'un fichier a plus d'une ligne dans une condition BASH?

Je dois vérifier si un fichier a plus d'une ligne. J'ai essayé ceci:

if [ `wc -l file.txt` -ge "2" ]
then
    echo "This has more than 1 line."
fi


if [ `wc -l file.txt` >= 2 ]
then
    echo "This has more than 1 line."
fi

Ceux-ci ne font que signaler des erreurs. Comment puis-je vérifier si un fichier a plus d'une ligne dans une condition BASH?

11
Village

La commande:

wc -l file.txt

générera une sortie comme:

42 file.txt

avec wc vous indiquant utilement le nom du fichier. Il le fait dans le cas où vous consultez plusieurs fichiers en même temps et que vous voulez des statistiques individuelles et totales:

pax> wc -l *.txt
 973 list_of_people_i_must_kill_if_i_find_out_i_have_cancer.txt
   2 major_acheivements_of_my_life.txt
 975 total

Vous pouvez empêcher wc de le faire en fournissant ses données sur une entrée standard. Ainsi, il ne sait pas le nom du fichier:

if [[ $(wc -l <file.txt) -ge 2 ]]

La transcription suivante montre cela en action:

pax> wc -l qq.c
26 qq.c

pax> wc -l <qq.c
26

En passant, vous remarquerez que je suis également passé à utiliser [[ ]] et $().

Je préfère le premier parce qu'il a moins de problèmes en raison de la compatibilité ascendante (principalement avec le fractionnement de chaînes) et le dernier parce qu'il est beaucoup plus facile d'imbriquer des exécutables.

26
paxdiablo

Une possibilité pure (≥ 4) en utilisant mapfile:

#!/bin/bash

mapfile -n 2 < file.txt
if ((${#MAPFILE[@]}>1)); then
    echo "This file has more than 1 line."
fi

La variable intégrée mapfile stocke ce qu'elle lit à partir de stdin dans un tableau (MAPFILE par défaut), une ligne par champ. Utiliser -n 2 permet de lire au plus deux lignes (pour plus d'efficacité). Après cela, il vous suffit de vérifier si le tableau MAPFILE a plus d'un champ. Cette méthode est très efficace.

En tant que sous-produit, la première ligne du fichier est stockée dans ${MAPFILE[0]}, au cas où vous en auriez besoin. Vous découvrirez que le caractère de fin de ligne suivant n'est pas coupé. Si vous devez supprimer le caractère de fin de ligne suivant, utilisez l'option -t:

mapfile -t -n 2 < file.txt
5
gniourf_gniourf

Que diriez-vous:

if read -r && read -r
then
  echo "This has more than 1 line."
fi < file.txt

L'indicateur -r est nécessaire pour garantir que les caractères de continuation de ligne ne se plient pas à deux lignes, ce qui obligerait le fichier suivant à ne signaler qu'une ligne:

This is a file with _two_ lines, \
    but will be seen as one.
4
Scrutinizer
if [ `wc -l file.txt | awk '{print $1}'` -ge "2" ]
...

Vous devriez toujours vérifier ce que chaque sous-commande retourne. La commande wc -l file.txt renvoie la sortie au format suivant:

12 file.txt

Vous avez besoin de la première colonne - vous pouvez l'extraire avec awk ou cut ou tout autre utilitaire de votre choix.

3
plesiv

Si vous traitez des fichiers volumineux, cette commande awk est beaucoup plus rapide que d'utiliser wc:

awk 'BEGIN{x=0}{if(NR>1){x=1;exit}}END{if(x>0){print FILENAME,"has more than one line"}else{print FILENAME,"has one or less lines"}}' file.txt

1
tungufoss