Trouver des files dont le nom est de 4 caractères

Je voudrais find des files dont le nom a seulement 4 caractères.

Exemple, il y a trois files sous /tmp :

 $ ls /tmp txt file linux 

La sortie ne doit afficher que le file car il ne comporte que 4 caractères.

Utilisez le ? caractère générique pour le stockage de files:

 ls -d /tmp/???? 

Cela imprimera tous les files et directorys dont le nom de file est long de 4 caractères.

Comme suggéré par @roaima, l'indicateur -d empêchera ls d'afficher le contenu des sous-directorys correspondant au model.

Liste des files dans /tmp uniquement:

 cd /tmp find . ! -name . -prune -path './????' -type f 

Répertoriez les files dans /tmp récursivement:

 find /tmp -path '*/????' -type f 

Essayer:

 find /tmp -type f -print| awk -F/ ' length($NF) == 4 ' 

Qu'est-ce que awk fait:

  • En utilisant / comme séparateur de champs,
  • Recherche du nom $NF file $NF (dernier champ)
  • length calcul
  • Et vérifiez si la valeur est 4, puis imprimez-la.

Cela me semble comme le moyen le plus simple de find un file de quatre octets:

 find /tmp -type f -size 4c 

Edit: pour find un nom de file de quatre octets:

 find /tmp -type f -name '????' 

Il y a aussi une solution perl (5.10 ou plus récente):

 perl -E 'say for </tmp/????>;' 

Une version légèrement plus flexible où vous pouvez spécifier la longueur désirée:

 perl -E 'my $w = "?" x shift; say for </tmp/$w>;' 4 

En supposant que vous utilisez bash, vous pouvez faire ce qui suit:

 shopt -s globstar shopt -s nullglob filearray=(/tmp/**/????) 

Cela mettra la list des files que vous voulez dans un tableau filearray . Les nouvelles lignes (et d'autres caractères exotiques) dans le nom de file seront traitées correctement.

La définition de globstar permet à ** dans les templates glob de faire correspondre les sous-directorys, en donnant la search récursive requirejse.

La définition de nullglob entraîne simplement l'expansion de l'extension si aucune correspondance n'est trouvée. Sinon, il s'étendra à lui-même, ce qui n'est probablement pas ce que vous voulez.

"/ tmp /" prend 5 caractères. C'est pourquoi il y a "9" (5 + 4) dans le test

 for i in /tmp/* ; do [ "${#i}" -eq 9 ] && printf %s\\n "$i"; done 

ou

 for i in /tmp/* ; do i="${i#/tmp/}"; # to get rid of /tmp/ [[ "${#i}" -eq 4 ]] && printf %s\\n "$i"; # there is 4 in test! done 

FWIW. Il n'échoue pas sur newline (@cuonglm), peut être facilement converti pour ne listr que 140 noms de files longs (@don_crissti).

Etant donné que le shell est exécuté par le shell, il n'est même pas nécessaire d'appeler ls ou find, echo fait l'affaire:

 $ echo /tmp/???? /tmp/file $ 

La seule chose est, s'il n'y a pas de file dont le nom est de 4 caractères, il va juste imprimer

 /tmp/???? 

Vous pouvez vouloir un script bash one-liner qui vérifie cela et imprime également un file par ligne:

 pattern=/tmp/????? ; for f in $pattern ; do if [ $f != "$pattern" ] ; then echo $f ; fi ; done 

Que diriez-vous:

 ls /tmp | grep -e '^.\{4\}$' 

pour une réponse basée sur grep .