Je voudrais utiliser les lignes provenant de "wc" comme variables. Par exemple:
echo 'foo bar' > file.txt
echo 'blah blah blah' >> file.txt
wc file.txt
2 5 23 file.txt
J'aimerais associer quelque chose comme $lines
, $words
et $characters
aux valeurs 2
, 5
et 23
. Comment puis-je faire cela en bash?
Il existe d’autres solutions, mais une solution simple que j’utilise habituellement consiste à placer la sortie de wc
dans un fichier temporaire, puis à lire à partir de là:
wc file.txt > xxx
read lines words characters filename < xxx
echo "lines=$lines words=$words characters=$characters filename=$filename"
lines=2 words=5 characters=23 filename=file.txt
L'avantage de cette méthode est qu'il n'est pas nécessaire de créer plusieurs processus awk
, un pour chaque variable. L'inconvénient est que vous avez besoin d'un fichier temporaire, que vous devez supprimer par la suite.
Attention, cela ne fonctionne pas:
wc file.txt | read lines words characters filename
Le problème est que la canalisation vers read
crée un autre processus et que les variables y sont mises à jour, elles ne sont donc pas accessibles dans le shell appelant.
Edit: ajout de solution par arnaud576875:
read lines words chars filename <<< $(wc x)
Fonctionne sans écrire dans un fichier (et n’a pas de problème de pipe). C'est bash spécifique.
De la bash manuel:
Here Strings
A variant of here documents, the format is:
<<<Word
The Word is expanded and supplied to the command on its standard input.
La clé est le bit "Word is expand".
En pure bash: (pas de awk)
a=($(wc file.txt))
lines=${a[0]}
words=${a[1]}
chars=${a[2]}
Cela fonctionne en utilisant les tableaux de bash. a=(1 2 3)
crée un tableau avec les éléments 1, 2 et 3. Nous pouvons ensuite accéder à des éléments séparés avec la syntaxe ${a[indice]}
.
Alternative: (à base de solution gonvalée)
read lines words chars <<< $(wc x)
Ou en sh:
a=$(wc file.txt)
lines=$(echo $a|cut -d' ' -f1)
words=$(echo $a|cut -d' ' -f2)
chars=$(echo $a|cut -d' ' -f3)
Juste pour ajouter une autre variante -
set -- `wc file.txt`
chars=$1
words=$2
lines=$3
Ceci évidemment clobbers $*
et les variables associées. Contrairement à certaines des autres solutions proposées ici, il est portable sur d’autres coques Bourne.
lines=`wc file.txt | awk '{print $1}'`
words=`wc file.txt | awk '{print $2}'`
...
vous pouvez également stocker le résultat wc
quelque part en premier .. et le parser ensuite .. si vous êtes pointilleux en matière de performance :)
Je voulais stocker le nombre de fichiers csv dans une variable. Ce qui suit a fonctionné pour moi:
CSV_COUNT=$(ls ./pathToSubdirectory | grep ".csv" | wc -l | xargs)
Vous pouvez affecter une sortie à une variable en ouvrant un sous-shell:
$ x=$(wc some-file)
$ echo $x
1 6 60 some-file
Maintenant, afin d’obtenir les variables séparées, l’option la plus simple est d’utiliser awk
:
$ x=$(wc some-file | awk '{print $1}')
$ echo $x
1
declare -a result
result=( $(wc < file.txt) )
lines=${result[0]}
words=${result[1]}
characters=${result[2]}
echo "Lines: $lines, Words: $words, Characters: $characters"