web-dev-qa-db-fra.com

Lors du comptage de lignes avec wc, n’imprimez pas d’erreur chaque fois qu’il s’agit d’un répertoire

Je veux compter le nombre total de lignes dans tous les fichiers /etc mais pas les fichiers dans les sous-répertoires. J'ai donc saisi: wc -l /etc/* | tail -1 et le résultat obtenu est le suivant:

xxxx is a directory 
yyyy is a directory
total 1752

Ma question est la suivante: comment puis-je supprimer (supprimer) ces commentaires et existe-t-il une meilleure façon de faire ce type de comptage?

12
Hamza

Vous pouvez envoyer les messages d'erreur à/dev/null

$ wc -l /etc/* 2>/dev/null | tail -1

Avec cette commande, vous ne voyez que le nombre de lignes dans les fichiers qui sont lisibles par tout le monde. Pour voir le nombre de lignes de tous les fichiers, vous devez élever la commande avec Sudo.

$ Sudo wc -l /etc/* 2>/dev/null | tail -1
14
L. D. James

Isoler les fichiers et exécuter wc sur eux

Ce que wc -l /etc/* fait est que * s'étendra à tous les éléments du répertoire /etc/. L’objectif est donc d’isoler les fichiers et d’appliquer wc dessus. Il y a plusieurs façons de le faire.

pour boucle avec test

La commande test, ou plus fréquemment abrégée en [ peut être utilisée pour déterminer si un élément est un fichier normal, comme ceci:

[ -f "$FILE" ]

Par conséquent, nous pouvons parcourir tous les éléments de /etc/ et exécuter wc dessus si et seulement si la commande ci-dessus renvoie la valeur true. Ainsi:

for i in /etc/*; do [ -f "$i" ] && wc -l "$i" ; done             

trouver

Nous pouvons également utiliser find avec -maxdepth, -type et -exec flags

find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} +

  • -maxdepth indique à quelle profondeur se trouve la structure de répertoires; La valeur 1 signifie que seuls les fichiers du répertoire que nous voulons.
  • -type f lui dit de rechercher des fichiers normaux, OR (représenté par l'indicateur -o) pour les liens syboliques (représentés par type l). Toute cette qualité est entre crochets () échappé avec \ de sorte que Shell les interprète dans le cadre de la commande find, plutôt que de quelque chose d'autre.
  • La structure -exec COMMAND {} + exécute ici la commande que nous lui donnons, + indiquant de prendre tous les fichiers trouvés et de les fourrer en tant qu'arguments de ligne de commande dans la COMMANDE.

Pour produire le total, nous pourrions diriger la sortie vers tail comme suit

$ find /etc/ -maxdepth 1 \( -type f -o -type l \) -exec wc -l {} + | tail -n 1           
[Sudo] password for xieerqi: 
 11196  total

Note latérale

Il est plus facile de simplement utiliser wc -l /etc/* 2>/dev/null | tail -1, comme dans la réponse de L. D. James. Toutefois, find devrait faire partie de l'habitude de traiter des fichiers afin d'éviter de traiter des noms de fichiers difficiles. Pour plus d’informations à ce sujet, lisez l’essai Comment traiter correctement les noms de fichiers

8

find le fait facilement:

Sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*')

Sortie:

...
828 /etc/mime.types
25 /etc/ts.conf
66 /etc/inputrc
 0 /etc/subgid-
8169 total

MAIS si vous souhaitez simplement afficher le nombre et rien d'autre :

Sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | grep total | awk '{print $1}'

ÉDITE: newlines erreur kos l’emporte. Seulement en utilisant -exec le rectifie. De plus, /etc ne contient pas de tels fichiers.

Sortie:

8169

Comme indiqué par kos , la commande ci-dessus peut être réduite à:

Sudo wc -l $(find /etc/ -maxdepth 1 -type f -iname '*') | awk 'END {print $1}'

ÉDITE: newlines erreur kos l’emporte. Seulement en utilisant -exec le rectifie. De plus, /etc ne contient pas de tels fichiers.

Sortie:

8169
5
Raphael

En utilisant z-Shell (zsh), la reine du coquilles , au lieu de bash.

Sudo wc -l /etc/*(.) | tail -1
2
A.B.