obtenir juste l'entier de wc dans bash


115

Existe-t-il un moyen d'obtenir l'entier que wc renvoie dans bash?

Fondamentalement, je veux écrire les numéros de ligne et le nombre de mots à l'écran après le nom du fichier.

output: filename linecount wordcount Voici ce que j'ai jusqu'à présent:

files=`ls`
for f in $files;
do
        if [ ! -d $f ] #only print out information about files !directories
        then
                # some way of getting the wc integers into shell variables and then printing them
                echo "$f $lines $ words"
        fi
done

Réponses:


57

Vous pouvez utiliser la cutcommande pour obtenir uniquement le premier mot de wcla sortie de (qui est le nombre de lignes ou de mots):

lines=`wc -l $f | cut -f1 -d' '`
words=`wc -w $f | cut -f1 -d' '`

5
Exécuter wc deux fois pour le même fichier est inefficace.
gawi

3
C'est vrai, c'est pourquoi je pense que la réponse de James Broadhead est bien meilleure. Je n'ai pas pu cuttravailler sur la sortie complète de wc $fparce que le nombre d'espaces entre les champs varie.
casablanca

1
@casablanca Vous pouvez réduire le nombre d'espaces en utilisant «tr -s». J'ai répertorié des solutions plus portables à cette question dans ma réponse ci-dessous.
rouble

Puisque dans cette réponse, nous attribuons à une variable, nous pourrions tuer les espaces avec
cycollins

88

La réponse la plus simple qui soit:

wc < filename 

5
Mais ne produit pas la sortie souhaitée.
Dave Newton

bien sûr, il vous suffit de transmettre les paramètres appropriés que vous feriez de toute façon. par exemple, si vous le faites wc -c < file name, cela ne vous donnera que le nombre entier d'octets et rien d'autre.
BananaNeil

13
Mon point était que si vous allez répondre à une question (vieille de 1,5 an), autant mettre toutes les informations dans la réponse, c'est tout :)
Dave Newton

oups, relisez la question .. #fail, je cherchais comment obtenir uniquement les nombres entiers, et j'utilisais les informations de l'une des réponses, quand j'ai découvert une meilleure réponse, puis j'ai décidé de poster à ce sujet. désolé ..
BananaNeil

3
Vous avez répondu à Google, c'est ce qui compte. :-)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

82

Juste:

wc -l < file_name

fera le travail. Mais cette sortie inclut des espaces blancs préfixés comme wcalignant à droite le nombre.


3
Pour obtenir juste le nombre de lignes sans espace: wc -l < foo.txt | xargsref - stackoverflow.com/a/12973694/149428
Taylor Edmiston

1
Ainsi, alors que la commande produit une réponse avec des espaces de début, le questionneur affectait une variable et cela supprime automatiquement les espaces de début (du moins c'était mon expérience sur l'ancien OSX bash). En d'autres termes, il en lines=`wc -l < $f`résulte une variable "ligne" dont la valeur n'a pas d'espaces de début.
cycollins

Et si je joue avec Find? J'obtiens une erreur: find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -lfonctionne bien mais imprime chaque fichier. Si j'utilise, find . -path -prune -o -name "*.swift" -print0 | xargs -0 wc -l <j'obtiens une erreur. parse error near '\n'
Nuno Gonçalves

55
wc $file | awk {'print "$4" "$2" "$1"'}

Ajustez si nécessaire pour votre mise en page.

Il est également plus agréable d'utiliser la logique positive ("est un fichier") plutôt que le négatif ("pas un répertoire")

[ -f $file ] && wc $file | awk {'print "$4" "$2" "$1"'}

1
Sur mon Windows dans Cmder (bash 4.4.12) cela fonctionne: wc $file | awk '{print $4" "$2" "$1}'- apostrophes en dehors de {}.
Grzegorz Gierlik

36

Parfois, wc sort dans différents formats sur différentes plates-formes. Par exemple:

Sous OS X:

$ echo aa | wc -l

         1

En Centos:

$ echo aa | wc -l

1

Ainsi, n'utiliser que couper peut ne pas récupérer le numéro. Essayez plutôt de supprimer les caractères d'espacement:

$ echo aa | wc -l | tr -d ' '

23

Les réponses acceptées / populaires ne fonctionnent pas sous OSX.

Tous les éléments suivants doivent être portables sur bsd et linux.

wc -l < "$f" | tr -d ' '

OU

wc -l "$f" | tr -s ' ' | cut -d ' ' -f 2

OU

wc -l "$f" | awk '{print $1}'

11

Si vous redirigez le nom de fichier, wcil omet le nom de fichier à la sortie.

Frapper:

read lines words characters <<< $(wc < filename)

ou

read lines words characters <<EOF
$(wc < filename)
EOF

Au lieu d'utiliser forpour itérer sur la sortie de ls, faites ceci:

for f in *

qui fonctionnera s'il y a des noms de fichiers qui incluent des espaces.

Si vous ne pouvez pas utiliser de globulation, vous devez diriger dans une while readboucle:

find ... | while read -r f

ou utilisez la substitution de processus

while read -r f
do
    something
done < <(find ...)

Je vous ai quand même augmenté, mais vous n'avez pas besoin de rediriger le nom du fichier. Capturez-le simplement comme un champ supplémentaire. read lines words characters filename <<< $(wc "$f")Oh, et si vous étiez * pour être durci contre les espaces, vous voulez également double guillemet la var lorsque vous l'utilisez.
Bruno Bronosky

Utiliser une variable supplémentaire est en effet une autre façon de le faire, mais si vous n'utilisez pas la variable (peut-être que vous avez déjà le nom de fichier dans une variable - $fdans ce cas), ce n'est pas nécessaire. En outre, l'OP a demandé comment obtenir uniquement l'entier. Vous avez raison de citer une variable, mais je n'ai pas montré l'utilisation de la variable, j'ai donc omis de mentionner ce point. Le for f in *formulaire devrait presque toujours être utilisé au lieu d'utiliser la sortie de ls, comme vous le savez.
Suspendu jusqu'à nouvel ordre.

Je suis entièrement d'accord sur ce lspoint. Cela vous rapportera un prix. partmaps.org/era/unix/award.html#ls
Bruno Bronosky

Si vous ne voulez pas le nom du fichier, vous pouvez faire ceci:read lines words characters _ <<< $(wc "$f")

@EvanTeitelman: Comme discuté dans quelques commentaires ci-dessus le vôtre. $_est juste une variable différente.
Suspendu jusqu'à nouvel ordre.

3

Si le fichier est petit, vous pouvez vous permettre d'appeler wcdeux fois et utiliser quelque chose comme ce qui suit, ce qui évite de passer à un processus supplémentaire:

lines=$((`wc -l "$f"`))
words=$((`wc -w "$f"`))

Le $((...))est l' expansion arithmétique de bash. Il supprime tous les espaces de la sortie de wcdans ce cas.

Cette solution est plus logique si vous avez besoin soit le linecount ou le wordcount.


2

Et avec sed?

wc -l /path/to/file.ext | sed 's/ *\([0-9]* \).*/\1/'


1

Essayez ceci pour le résultat numérique:
nlines = $ (wc -l <$ myfile)


0

Essaye ça:

wc `ls` | awk '{ LINE += $1; WC += $2 } END { print "lines: " LINE  " words: " WC }'

Il crée un nombre de lignes et un nombre de mots (LINE et WC), et les augmente avec les valeurs extraites de wc (en utilisant 1 $ pour la valeur de la première colonne et 2 $ pour la seconde) et imprime enfin les résultats.


0

"Fondamentalement, je veux écrire les numéros de ligne et le nombre de mots à l'écran après le nom du fichier."

answer=(`wc $f`)
echo -e"${answer[3]}
lines:  ${answer[0]}
words:  ${answer[1]}
bytes:  ${answer[2]}"

Sorties: myfile.txt lignes: 10 mots: 20 octets: 120


0
files=`ls`
echo "$files" | wc -l | perl -pe "s#^\s+##"

Si vous utilisez perlquand même, autant faire le décompte des mots en Perl. Une approche plus économique serait de canaliser verstr -d '[:space:]'
tripleee
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.