Ordinaire quand je veux montrer le nom du premier fichier du répertoire que je tape:
ls raw/all | head -n 1
Mais cela prend du temps quand dans le répertoire il y a beaucoup de fichiers
Par exemple, pour dir avec près de 900 k fichiers, nous avons les mesures suivantes:
time ls raw/all | head -n 1
real 0m17.250s | 0m10.328s | 0m6.334s
user 0m3.224s | 0m3.884s | 0m3.192s
sys 0m0.544s | 0m0.664s | 0m0.572s
la boucle While sur tous les fichiers prend:
time ls raw/all | wc -l
real 0m6.455s | 0m5.869s | 0m5.228s
user 0m3.612s | 0m3.468s | 0m4.072s
sys 0m0.460s | 0m0.784s | 0m0.624s
Comment imprimer le nom du premier fichier de manière efficace?
C'est délicat. Deux approches:
approche 1; find
:
find . -mindepth 1 -print -quit
find
et -print
s le premier fichier trouvé et -quit
s immédiatement. -mindepth 1
empêchera de faire correspondre le .
lien dur du répertoire en cours.
Si vous êtes intéressé uniquement par les fichiers ordinaires, ajoutez -type f
:
find . -type f -print -quit
-mindepth 1
peut être supprimé alors que .
étant un répertoire ne correspond pas.
Approche 2; sh
, stdbuf
et awk
:
Notez que ARG_MAX
peut être déclenché pour un trop grand nombre de fichiers (la liste des arguments devenant trop longue, sur ARG_MAX
octets). Dans ce cas, utilisez l'approche 1.
printf
, echo
) pour imprimer le nom de fichier*
, pour effectuer le développement (l'ordre de classement doit être identique à ls
pour un locale
'LC_COLLATE
donné)stdbuf -o0
(stdbuf
est fourni avec GNU coreutils
) pour que le flux STDOUT de printf
/echo
soit sans tampon|
) le STDOUT de printf
/echo
à awk
et exit
après avoir imprimé le premier enregistrementawk
, stdbuf
(printf
) recevrait SIGPIPE
et serait tué.printf
pour obtenir les noms de fichiers séparés par ASCII NUL (\0
) et utiliser \0
comme séparateur d'enregistrement dans awk
pour traiter tous les cas Edge, dans la mesure où les noms de fichiers sont concernéMettre ensemble ces:
stdbuf -o0 printf '%s\0' * | awk 'BEGIN{RS="\0"} {print; exit}'