Je voudrais trouver des fichiers dont le nom ne comporte que 4 caractères.
Exemple, il y a trois fichiers sous /tmp
:
$ ls /tmp
txt
file
linux
La sortie ne doit afficher que file
car elle ne comporte que 4 caractères.
Utilisez le ?
caractère générique pour le remplacement de fichiers:
ls -d /tmp/????
Cela imprimera tous les fichiers et répertoires dont le nom de fichier est de 4 caractères.
Comme l'a suggéré @roaima, le -d
flag empêchera ls
d'afficher le contenu des sous-répertoires qui correspondent au modèle.
Lister les fichiers dans /tmp
seulement:
cd /tmp
find . ! -name . -Prune -path './????' -type f
Lister les fichiers dans /tmp
récursivement:
find /tmp -path '*/????' -type f
Essayer:
find /tmp -type f -print| awk -F/ ' length($NF) == 4 '
Ce que awk
fait:
/
comme séparateur de champ,$NF
(dernier champ)length
Il existe également 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 souhaitée:
Perl -E 'my $w = "?" x shift; say for </tmp/$w>;' 4
Cela me semble être le moyen le plus simple de trouver un fichier de quatre octets:
find /tmp -type f -size 4c
Edit: pour trouver un fichier nom de quatre octets:
find /tmp -type f -name '????'
En supposant que vous utilisez bash, vous pouvez effectuer les opérations suivantes:
shopt -s globstar
shopt -s nullglob
filearray=(/tmp/**/????)
Cela mettra la liste des fichiers que vous voulez dans un tableau filearray
. Les sauts de ligne (et autres caractères exotiques) dans le nom de fichier seront traités correctement.
La définition de globstar active **
dans les modèles globaux pour correspondre entre les sous-répertoires, donnant la recherche récursive requise.
La définition de nullglob entraîne simplement l'expansion à rien s'il n'y a pas de correspondance. Sinon, il se développera à 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 la nouvelle ligne (@cuonglm), peut être facilement converti pour ne lister que les noms de fichier de 140 caractères (@don_crissti).
Comme le globbing est fait par le Shell, il n'est même pas nécessaire d'appeler ls ou de trouver, echo fait l'affaire:
$ echo /tmp/????
/tmp/file
$
La seule chose est, s'il n'y a pas de fichier dont le nom est de 4 caractères, il imprimera simplement
/tmp/????
Vous voudrez peut-être un script bash à une ligne qui vérifie cela et imprime également un fichier par ligne:
pattern=/tmp/????? ; for f in $pattern ; do if [ $f != "$pattern" ] ; then echo $f ; fi ; done