Comment faire pour que «wc -l» n'imprime que le nombre de lignes sans nom de fichier?

155
wc -l file.txt

génère le nombre de lignes et le nom du fichier.

J'ai juste besoin du numéro lui-même (pas du nom du fichier).

je peux le faire

 wc -l file.txt | awk '{print $1}'

Mais peut-être existe-t-il un meilleur moyen?

PoGibas
la source
13
wc -l < file.txtfait le travail avec précision et concision.
Jonathan Leffler
2
Double possible de obtenir juste l'entier de wc dans bash
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
3
C'est une question que j'ai regardée deux fois maintenant. Ce comportement de wc est peu intuitif et anti-paradigmatique pour la concision habituelle de -nix. Cette lacune est là pour une raison, car vous ne voulez exactement pas contourner toutes sortes de redondances moelleuses. Après tout, je connais le nom du fichier, n'est-ce pas? Ce que je veux, c'est le nombre de lignes.
Peter - Réintégrer Monica

Réponses:

217

Essayez de cette façon:

wc -l < file.txt
Norman Ramsey
la source
5
Sous AIX, ksh, il y aura toujours un espace précédant le nombre. Nous devons utiliser | awk '{print $ 1}' ou une coupe, pour couper les espaces. Une autre façon de couper serait de fermer avec un écho.
rao
@rao est correct, cela ajoutera un espace avant le nombre. Ma solution résout ce problème et est plus simple que awk ou cut.
Desi Cochrane
@rao Il n'y a pas d'espace avec bash. D'où vient l'espace dans ksh? wc -lne devrait pas en émettre un, et pourquoi ksh ajouterait-il un espace à la sortie standard d'un programme?
Peter - Réintègre Monica le
Bien que ce soit la bonne solution de contournement (et il est assez facile que wc n'ait jamais été modifié), elle est probablement plus lente et peu intuitive. D'une part, je m'attendrais à quelque chose comme 4711 [stdin]la sortie.
Peter - Réintègre Monica
Pensez également à l'appairer avec printf "%'d", qui prend soin de l'espace et imprime bien les grands nombres.
Leo
21
cat file.txt | wc -l

D'après la page de manuel (pour la version BSD, je n'ai pas de version GNU à vérifier):

Si aucun fichier n'est spécifié, l'entrée standard est utilisée et aucun nom de fichier n'est affiché. L'invite acceptera l'entrée jusqu'à la réception d'EOF, ou [^ D] dans la plupart des environnements.

pjmorse
la source
3
Je n'aime pas les chats - la concaténation prend trop de temps.
PoGibas
9
wc -l < file.txta le même effet.
pjmorse
@user: Testez-le. De loin, la partie la plus lente sera de lire le fichier sur le disque.
sarnold
11
@ user1286528 puis utilisez wc -l < file.txtpour éviter l'utilisation inutile de cat. Bien que vous soyez absolument fou si vous pensez que cela prend un temps notable.
hobbs
12

Pour ce faire sans l'espace de tête, pourquoi pas:

wc -l < file.txt | bc
Desi Cochrane
la source
J'obtiens des erreurs de syntaxe avec ceci (Ubuntu 14.04). Je pense qu'il y a un problème avec le nom de fichier.
MERose
Sur un RHEL 6.7, il génère des erreurs: $ wc -l fichier.csv | bc (standard_in) 1: erreur de syntaxe (standard_in) 1: caractère illégal: N (standard_in) 1: erreur de syntaxe (standard_in) 1: erreur de syntaxe
Rodrigo Hjort
3
J'obtiens également une erreur d'analyse, mais vous pouvez combiner cela avec l'autre réponse à utiliser wc -l < file.txtpour corriger l'erreur d'analyse et supprimer l'espace:wc -l < file.txt | bc
jangosteve
11

Que diriez-vous

wc -l file.txt | cut -d' ' -f1

c'est-à-dire diriger la sortie de wcinto cut(où les délimiteurs sont des espaces et ne sélectionner que le premier champ)

Neil Albert
la source
4
ce n'est pas mieux que l' wc -l file.txt | awk '{print $1}'OP essayé.
doubleDown
1
Plus rapide que la wc -l < file.txtméthode. Mais doit utiliser | cut -d' ' -f2sur BSD, tant que la wccommande renvoie un espace de début, exemple: "34068289 file.txt", au lieu de "34068289 file.txt".
Sopalajo de Arrierez
@doubleDown Eh bien, utiliser awk, c'est comme utiliser une machine CNC pour couper une planche au lieu d'une scie. Utilisez une scie pour scier.
Peter - Réintègre Monica
5

Comparaison des techniques

J'ai eu un problème similaire en essayant d'obtenir un nombre de caractères sans le premier espace blanc fourni par wc, ce qui m'a conduit à cette page. Après avoir essayé les réponses ici, voici les résultats de mes tests personnels sur Mac (BSD Bash). Encore une fois, c'est pour le nombre de caractères; pour le nombre de lignes que vous feriez wc -l. echo -nomet le saut de ligne de fin.

FOO="bar"
echo -n "$FOO" | wc -c                          # "       3"    (x)
echo -n "$FOO" | wc -c | bc                     # "3"           (√)
echo -n "$FOO" | wc -c | tr -d ' '              # "3"           (√)
echo -n "$FOO" | wc -c | awk '{print $1}'       # "3"           (√)
echo -n "$FOO" | wc -c | cut -d ' ' -f1         # "" for -f < 8 (x)
echo -n "$FOO" | wc -c | cut -d ' ' -f8         # "3"           (√)
echo -n "$FOO" | wc -c | perl -pe 's/^\s+//'    # "3"           (√)
echo -n "$FOO" | wc -c | grep -ch '^'           # "1"           (x)
echo $( printf '%s' "$FOO" | wc -c )            # "3"           (√)

Je ne me fierais pas à la cut -f*méthode en général, car elle nécessite que vous connaissiez le nombre exact d'espaces de début qu'une sortie donnée peut avoir. Et grepcelui fonctionne pour compter les lignes, mais pas les caractères.

bcest le plus concis awket perlsemble un peu exagéré, mais ils devraient tous être assez rapides et suffisamment portables.

Notez également que certains d'entre eux peuvent également être adaptés pour couper les espaces blancs environnants à partir de chaînes générales (avec echo `echo $FOO`une autre astuce intéressante).

Beejor
la source
1
echo $(printf '%s' "$FOO" | wc -c)est l'une des rares occasions où echoavec une commande la subshitution n'est pas inutile.
tripleee
@tripleee Whoa ... basé sur votre code, echo `echo $FOO`;agit également comme une commande String.trim () sur une variable! C'est incroyablement pratique. J'ajouterai également votre ligne à ma réponse.
Beejor
Peut-être pour le contexte, voir aussi Quand enrouler les guillemets autour d'une variable shell
tripleee
... ainsi que Pourquoi vaut printfmieux que echo?
tripleee
4

Que diriez-vous

grep -ch "^" file.txt
MeIsMich
la source
3
Agréable. Utilisation très originale / créative de grepmais en vérifiant cela, il s'avère (sans surprise) être 2x à 6x plus lent que la wcméthode la plus simple / directe de mes tests.
arielf
3

De toute évidence, il existe de nombreuses solutions à cela. En voici un autre cependant:

wc -l somefile | tr -d "[:alpha:][:blank:][:punct:]"

Cela ne produit que le nombre de lignes, mais le caractère de fin de ligne ( \n) est présent, si vous ne le souhaitez pas non plus, remplacez-le [:blank:]par [:space:].

Bouchaala Reda
la source
Cela pose le problème lorsque le nom de fichier contient un numéro. Par exemple, pour le fichier test9avec 1 ligne, le résultat sera 19.
Raphael Ahrens
1

Le meilleur moyen serait tout d'abord de trouver tous les fichiers dans le répertoire, puis d'utiliser AWK NR (Variable du nombre d'enregistrements)

ci-dessous est la commande:

find <directory path>  -type f | awk  'END{print NR}'

exemple : - find /tmp/ -type f | awk 'END{print NR}'

user128364
la source
0

Cela fonctionne pour moi en utilisant la normale wc -let sedpour supprimer tout caractère qui n'est pas un nombre.

wc -l big_file.log | sed -E "s/([a-z\-\_\.]|[[:space:]]*)//g"

# 9249133
Joseluisq
la source