Dans Bash, je voudrais créer une fonction qui renvoie le nom de fichier du fichier le plus récent qui correspond à un certain modèle. Par exemple, j'ai un répertoire de fichiers comme:
Directory/
a1.1_5_1
a1.2_1_4
b2.1_0
b2.2_3_4
b2.3_2_0
Je veux le fichier le plus récent commençant par «b2». Comment faire cela dans bash? J'ai besoin de cela dans mon ~/.bash_profile
script.
Réponses:
La
ls
commande a un paramètre-t
à trier par heure. Vous pouvez ensuite récupérer le premier (le plus récent) avechead -1
.Mais attention: pourquoi vous ne devriez pas analyser la sortie de ls
Mon opinion personnelle: l'analyse
ls
n'est dangereuse que lorsque les noms de fichiers peuvent contenir des caractères amusants comme des espaces ou des retours à la ligne. Si vous pouvez garantir que les noms de fichiers ne contiennent pas de caractères amusants, l'analyse syntaxiquels
est tout à fait sûre.Si vous développez un script destiné à être exécuté par de nombreuses personnes sur de nombreux systèmes dans de nombreuses situations différentes, je vous recommande vivement de ne pas analyser
ls
.Voici comment faire "correctement": Comment puis-je trouver le dernier fichier (le plus récent, le plus ancien, le plus ancien) dans un répertoire?
la source
ls
, leprintf "%s\n" b2* | head -1
fera pour vous.b2.10_5_2
cette solution tue.La combinaison de
find
etls
fonctionne bien pourLa solution:
Décomposons-le:
Avec
find
nous pouvons faire correspondre tous les fichiers intéressants comme celui-ci:puis en utilisant,
-print0
nous pouvons passer tous les noms de fichiers en toute sécuritéls
comme ceci:des
find
paramètres et des modèles de recherche supplémentaires peuvent être ajoutés icils -t
triera les fichiers par heure de modification (le plus récent en premier) et l'imprimera un par ligne. Vous pouvez utiliser-c
pour trier par heure de création. Remarque : cela rompra avec les noms de fichiers contenant des nouvelles lignes.Enfin
head -1
nous obtient le premier fichier dans la liste triée.Remarque:
xargs
utilisez les limites du système à la taille de la liste d'arguments. Si cette taille dépasse,xargs
appellerals
plusieurs fois. Cela interrompra le tri et probablement aussi la sortie finale. Courirpour vérifier les limites de votre système.
Remarque 2: à utiliser
find . -maxdepth 1 -name "my-pattern" -print0
si vous ne souhaitez pas rechercher de fichiers dans les sous-dossiers.Note 3: Comme indiqué par @starfry - l'
-r
argument pourxargs
empêche l'appel dels -1 -t
, si aucun fichier ne correspond aufind
. Merci pour la suggestion.la source
find . -name "my-pattern" ... -print0
me donnefind: paths must precede expression: `...'
...
signifie «plus de paramètres». Omettez-le simplement si vous n'en avez pas besoin.-r
à la ligne de commande xargs qui dit à xargs de ne pas exécuter sa ligne de commande s'il ne reçoit rien sur son entrée standard.-r
à la réponse.Voici une implémentation possible de la fonction Bash requise:
Il utilise uniquement des fonctions intégrées Bash et doit gérer les fichiers dont les noms contiennent des retours à la ligne ou d'autres caractères inhabituels.
la source
nullglob_shopt=$(shopt -p nullglob)
et ensuite$nullglob
remettrenullglob
ce qu'il était avant.$()
ou les backticks) car elle est lente, en particulier sous Cygwin, même lorsque la commande n'utilise que des builtins. En outre, le contexte de sous-shell dans lequel les commandes sont exécutées peut parfois les amener à se comporter de manière inattendue. J'essaie également d'éviter de stocker des commandes dans des variables (commenullglob_shopt
) car de très mauvaises choses peuvent arriver si vous obtenez la valeur de la variable incorrecte.cat
!». Même si cela demande plus de travail, cela a l'avantage de montrer les concepts des gens. Avoir un +1!Les noms de fichiers inhabituels (comme un fichier contenant le
\n
caractère valide peut faire des ravages avec ce type d'analyse. Voici une façon de le faire en Perl:C'est une transformation schwartzienne utilisée ici.
la source
Vous pouvez utiliser
stat
avec un fichier glob et un decorate-sort-undecorate avec le temps de fichier ajouté sur le devant:la source
stat
, si je me souviens bien de ses options. Pour obtenir une sortie similaire sur d'autres plates-formes, vous pouvez utiliserstat -c $'%Y\t%n' b2* | sort -rn | head -n1 | cut -f2-
Incantation de fonction de magie noire pour ceux qui veulent la
find ... xargs ... head ...
solution ci-dessus, mais sous forme de fonction facile à utiliser pour que vous n'ayez pas à penser:Impressions:
Lequel est:
Le nom de fichier avec le plus ancien horodatage modifié du fichier sous le répertoire donné correspondant au modèle donné.
la source
Utilisez la commande find.
En supposant que vous utilisez Bash 4.2+, utilisez
-printf '%T+ %p\n'
pour la valeur d'horodatage du fichier.Exemple:
Pour un script plus utile, consultez le script de recherche le plus récent ici: https://github.com/l3x/helpers
la source
Il existe un moyen beaucoup plus efficace d'y parvenir. Considérez la commande suivante:
Cette commande trouve le dernier fichier produit il y a exactement une minute avec la recherche générique sur "b2 *". Si vous voulez des fichiers des deux derniers jours, vous ferez mieux d'utiliser la commande ci-dessous:
Le "." représente le répertoire courant. J'espère que cela t'aides.
la source