Si vous vous tenez tranquillement dans les couloirs d'Unix et Linux et écoutez attentivement, vous entendrez une voix fantomatique, gémissant pitoyablement, «Et les noms de fichiers qui contiennent des sauts de ligne?»
ls -d *snp* | wc -l
ou, de manière équivalente ,
printf "%s\n" *snp* | wc -l
affichera tous les noms de fichiers qui contiennent snp, chacun suivi d'un retour à la ligne,
mais également tous les retours à la ligne dans les noms de fichiers , puis comptera le nombre de lignes dans la sortie. S'il existe un fichier dont le nom est
f o o
s n p \n
b a r
. t s v
alors ce nom sera écrit comme
foosnp
bar.tsv
qui, bien sûr, comptera pour deux lignes.
Il existe quelques alternatives qui font mieux dans au moins certains cas:
printf "%s\n" * | grep -c snp
qui compte les lignes qui contiennent snp, donc l' foosnp(\n)bar.tsvexemple ci-dessus ne compte qu'une seule fois. Une légère variation à ce sujet est
ls -f | grep -c snp
Les deux commandes ci-dessus diffèrent en ce que:
- Le
ls -fcomprendra des fichiers dont les noms commencent par .; ce printf … *n'est pas le cas, sauf si l' dotgloboption shell est définie.
printfest un shell intégré; lsest une commande externe. Par conséquent, le lspeut utiliser un peu plus de ressources.
- Lorsque le shell traite a
*, il trie les noms de fichiers;
ls -fne trie pas les noms de fichiers. Par conséquent, le lspeut utiliser un peu moins de ressources.
Mais ils ont quelque chose en commun: ils donneront tous les deux des résultats erronés en présence de noms de fichiers qui contiennent un retour à la ligne et qui ont à la snpfois avant et après le retour à la ligne .
Un autre:
filenamelist=(*snp*)
echo ${#filenamelist[@]}
Cela crée une variable de tableau shell répertoriant tous les noms de fichiers qui contiennent snp, puis signale le nombre d'éléments dans le tableau. Les noms de fichiers sont traités comme des chaînes, pas comme des lignes, donc les sauts de ligne intégrés ne sont pas un problème. Il est concevable que cette approche puisse avoir un problème si le répertoire est énorme, car la liste des noms de fichiers doit être conservée dans la mémoire du shell.
Encore un autre:
Plus tôt, lorsque nous l'avons dit printf "%s\n" *snp*, la printfcommande a répété (réutilisé) la "%s\n"chaîne de formatage une fois pour chaque argument dans l'expansion de *snp*. Ici, nous faisons un petit changement:
printf "%.0s\n" *snp* | wc -l
Cela va répéter (réutiliser) la "%.0s\n"chaîne de formatage une fois pour chaque argument dans l'expansion de *snp*. Mais "%.0s"signifie imprimer les premiers caractères zéro de chaque chaîne - c'est-à-dire rien. Cette printfcommande ne produira qu'une nouvelle ligne (c'est-à-dire une ligne vierge) pour chaque fichier qui contient snpson nom; puis wc -lles comptera. Et, encore une fois, vous pouvez inclure les .fichiers en définissant dotglob.