Est-il possible de la sortie de find … -exec ls -ls ;
trié par ordre alphabétique, par nom de fichier?
Voici ma commande cron:
find /home/setefgge/public_html -type f -ctime -1 -exec ls -ls {} \;
Cette commande fonctionne bien, pour la plupart. Mais les résultats ne sont pas triés dans une séquence significative. Il serait très utile de les trier par le champ du nom de fichier.
Je suppose que vos noms de fichiers ne contiennent pas de retours à la ligne.
find /home/setefgge/public_html -type f -ctime -1 -exec ls -nls {} + | sort -k 10
L'utilisation de +
Au lieu de ;
Pour terminer l'action -exec
Accélère la procédure en regroupant les appels de ls
. Vous pouvez trier en passant par la commande sort
; dites-lui de commencer le tri au 10e champ (les 9 premiers sont les métadonnées: blocs, autorisations, nombre de liens, utilisateur, groupe, taille et 3 champs date/heure). L'option -n
Indique à ls
d'utiliser des valeurs numériques pour l'utilisateur et le groupe, ce qui évite le risque que les noms d'utilisateur ou de groupe contiennent des espaces.
Alternativement, avec zsh, vous pouvez vous en sortir sans aucune hypothèse sur n'importe quel nom en utilisant qualificatifs glob pour collecter et trier les fichiers et zargs
pour exécuter ls
plusieurs fois si la ligne de commande est trop longue. Vous avez besoin de GNU ls
(en particulier son option -f
) Pour éviter un nouveau tri par ls
(une autre approche serait d'émuler ls
avec zsh zstat
).
autoload -U zargs
zargs -- /home/setefgge/public_html/**/*(.c-2) -- ls -lnsf
POSIX a ceci à dire sur les dates dans un ls
-l
ong liste:
Le
<date and time>
Le champ doit contenir la date et l'horodatage appropriés de la dernière modification du fichier. Dans l'environnement local POSIX, le champ doit être l'équivalent de la sortie de la commande de date suivante:
date "+%b %e %H:%M"
... si le fichier a été modifié au cours des six derniers mois, ou:
date "+%b %e %Y"
En tenant compte de cela, et en vous assurant que s'il y a des sauts de ligne dans un nom de fichier, ils sont correctement globalisés avec le _ également spécifié par POSIX ls -q
, il est relativement facile de préparer une expression régulière pour un résultat ls
sans find
du tout:
d=$(date "+%b %e") y=$(date --date=yesterday "+%b %e")
echo "$d" "$y"
###OUTPUT###
Jul 5 Jul 4
grep
pour cela et vous ne retournerez que des lignes contenant les chaînes représentant les dates d'aujourd'hui ou d'hier. La commande suivante ajoute un peu à cela:
ls -alRcq | sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"
ls
les options comprennent:
-a
renvoie tous les fichiers d'un répertoire - y compris ceux qui commencent par .dot
-l
longue liste-R
liste récursivement tous les répertoires enfants-c
afficher l'heure de modification plutôt que l'heure d'accès-q
retourner le Shell glob ?
plutôt que non imprimable ou \t
ab caractères dans un nom de fichierCes résultats sont transmis sur le |pipe
fichier vers sed
qui correspond uniquement:
-
(en d'autres termes - pas d
pour le répertoire) qui contient également votre date
.La sortie ressemble à ceci:
ls -alRcq --color=always |
sed "1H;/^-/!{/./d;N;h};/$d\|$y/!d;x;/\n/p;g"
###OUTPUT###
.:
-rw------- 1 mikeserv mikeserv 2086 Jul 4 10:52 .bash_history
-rw------- 1 mikeserv mikeserv 2657 Jul 4 15:20 .lesshst
-rw-r--r-- 1 mikeserv mikeserv 681 Jul 5 05:18 .zdirs
-rw------- 1 mikeserv mikeserv 750583 Jul 5 08:28 .zsh_history
-rw-r--r-- 1 mikeserv mikeserv 166 Jul 4 23:02 Terminology.log
-rw-r--r-- 1 mikeserv mikeserv 433568 Jul 4 13:34 shot-2014-06-22_17-10-16.jpg
-rw-r--r-- 1 mikeserv mikeserv 445192 Jul 4 13:34 shot-2014-06-22_17-11-06.jpg
./.cache/efreet:
-rw------- 1 mikeserv mikeserv 37325 Jul 4 22:51 desktop_localhost_C.eet
-rw------- 1 mikeserv mikeserv 37325 Jul 4 23:30 desktop_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv 24090 Jul 4 22:51 desktop_util_localhost_C.eet
-rw------- 1 mikeserv mikeserv 24090 Jul 4 23:30 desktop_util_localhost_en_US.eet
-rw------- 1 mikeserv mikeserv 16037 Jul 4 23:30 icon_themes_localhost.eet
-rw------- 1 mikeserv mikeserv 3117 Jul 4 23:30 icons___efreet_fallback_localhost.eet
-rw------- 1 mikeserv mikeserv 768039 Jul 4 23:30 icons_gnome_localhost.eet
-rw------- 1 mikeserv mikeserv 18589 Jul 4 23:30 icons_hicolor_localhost.eet
./.config:
-rw-r--r-- 1 mikeserv mikeserv 30 Jul 4 19:10 pavucontrol.ini
./.config/chrome:
-rw-r--r-- 1 mikeserv mikeserv 94332179 Jul 4 13:36 conf.tar.lz4.bak
Oui, cela fonctionne même avec LS_COLORS
- ce qui est probablement une faible priorité pour votre cron
bien sûr, mais bon, vos options sont ouvertes.
Dans tous les cas, cela offre des avantages importants par rapport à d'autres solutions possibles.
En premier lieu find
+ ls
implique plusieurs invocations - cela implique seulement un seul processus ls
, et c'est pourquoi il est capable de tout trier de manière fiable - ce qu'il fait par par défaut - et donc sort
est également rendu accessoire.
Toute solution impliquant find
et sort
et ls
fait à peu près tout deux fois le travail . ls
et find
résoudront tous les deux les chemins d'accès et stat
tous les fichiers. ls
et sort
trieront tous les résultats. Il est probablement préférable d'utiliser à la place le seul ls
.
Bien sûr, il y a les parties date
et sed
de cette réponse. Ce qui est important à noter à ce sujet, c'est que vous faites la partie difficile et obtenez d'abord l'expression régulière - et une seule fois - et ensuite vous ne taillez qu'une seule liste de résultats plutôt que de dire, obtenir des résultats, obtenir des résultats, trier les résultats et trier les résultats.
Cela ne se casse pas sur les noms de fichiers contenant des sauts de ligne, comme le feront probablement d'autres solutions. Cette solution a ses propres mises en garde - que j'explique ensuite - mais elles sont infimes et faciles à gérer. À mon avis, c'est la solution la plus robuste ici.
Il existe deux cas dans lesquels la commande ci-dessus peut vous poser des problèmes. Le premier implique le ?
globs dans les noms de fichiers - alors que tel est déjà une solution plus robuste que toute autre proposée ici, et la probabilité que vous rencontriez un ?
du tout est assez petit en soi, il est possible que la résolution de ces globes corresponde à plusieurs noms de fichiers. Veuillez consulter this pour plus d'informations à ce sujet.
L'autre possibilité implique un faux positif - par exemple si vous avez un nom de fichier correspondant réellement à la chaîne date
que nous recherchons avec grep
mais qui n'a pas été réellement modifié aucun de ces jours. Je ne compte pas sur le fait que ce soit un problème, mais, si c'est le cas, posez des questions à ce sujet et je peux probablement vous aider à rendre l'expression plus précise afin de gérer cela.
Pourquoi ne pas diriger le résultat de la recherche par tri, puis exécuter ls pour chacune des lignes?
find . -type f -ctime -1 | sort | while IFS= read -r filename; do ls -ls "$filename"; done
Vous pouvez réellement utiliser une combinaison de find, xargs et ls.
Voici un exemple de commande: find . -type f -print0 | xargs -0 ls -lt
find
recherchera récursivement tous les fichiers du répertoire courant.ls
en un seul appel (à condition que find
renvoie moins de ARG_MAX
des dossiers).ls -lt
triera ces fichiers par heure et formatera la sortieAfin de récupérer votre système ARG_MAX
vous pouvez taper:
$ getconf ARG_MAX
> 2621440