Comment listr le plus jeune file (sans parsingr ls!)

Donc, je sais que l'parsing est mauvaise! .

Aujourd'hui j'ai trouvé cette pépite:

FILENAME=`ls -t $READ_FOLDER | head -1` 

Donc, je crois que c'était à l'origine conçu pour saisir le nouveau nom de file, je veux maintenant l'adapter, pour prendre le 5ème file le plus récent, car le process est un peu lent et nous ne pouvons pas être sûr qu'ils ont été traité encore.

Je travaille dans bash, mais pas opposé à une solution générique sh aussi.

Vous pouvez utiliser GNU find pour listr les files avec le time modifié exprimé en epoch time, puis utilisez sort pour sortinger la list, enfin head et tail pour get le nom de file numéroté désiré:

 find . -maxdepth 1 -type f -printf '%T@ %p\n' | sort -k1,1nr | head -5 | tail -1 

Perlishly:

 #!/usr/bin/env perl use ssortingct; use warnings; my %files_by_mtime; foreach my $file ( glob ( "./*" ) ) { my ( $mtime ) = (stat($file))[9]; $files_by_mtime{$file} = $mtime; } foreach my $f ( sort { $files_by_mtime{$b} <=> $files_by_mtime{$a} } keys %files_by_mtime ) { print "$f $files_by_mtime{$f}\n"; } 

Réduire à:

 perl -e '%f = map { $_ => (stat)[9] } glob("./*");print "" . ( sort { $f{$b} <=> $f{$a} } keys %f )[4];' 

Où le "N" ème file est 4, car les arrays perl commencent à zéro.

En supposant que vous avez access aux outils GNU (vous le faites si vous utilisez Linux), j'utiliserais stat place. Par exemple:

 $ ls -l total 0 -rw-r--r-- 1 terdon terdon 0 Sep 15 16:49 file1 -rw-r--r-- 1 terdon terdon 0 Sep 15 16:39 file2 -rw-r--r-- 1 terdon terdon 0 Sep 15 16:29 file3 -rw-r--r-- 1 terdon terdon 0 Sep 15 16:19 file4 -rw-r--r-- 1 terdon terdon 0 Sep 15 16:09 file5 -rw-r--r-- 1 terdon terdon 0 Sep 15 15:59 file6 -rw-r--r-- 1 terdon terdon 0 Sep 15 15:49 file7 

Donc, le 5ème file le plus récent est file5 . Pour imprimer cela, vous pouvez faire:

 $ stat --printf '%Y %n\0' * | sort -zrnk1 | awk -vRS='\0' 'NR==5{sub(/^[^ ]* /,"",$0); print}' 

Vous pourriez ensuite facilement faire cela dans une fonction shell qui peut prendre N (5 dans votre exemple) comme argument. Il suffit d'append ces lignes à votre ~/.bashrc ou équivalent:

 nthfile() { stat --printf '%Y %n\0' * | sort -zrnk1 | awk -vRS='\0' -vn="$1" 'NR==n{sub(/^[^ ]* /,"",$0); print}' } 

Notez que cela vous montrera également les directorys. Si vous en avez besoin pour faire correspondre les files cachés ainsi exécutés (en supposant que vous utilisez bash) shopt -s dotglob avant la command ci-dessus.

Explication

  • stat --printf '%Y %n\0' * : pour chaque file ou directory du dossier en cours, imprimez la date de modification en secondes depuis l'époque ( %s ) et le nom du file \0 au lieu de \n . Cela nous permet de gérer correctement les noms de files contenant des caractères de nouvelle ligne.
  • sort -zrnk1 : sortinge la sortie dans l'ordre de sorting inversé ( -r ), du plus récent au plus ancien. Le -z dit sort pour attendre les lignes d'input terminées par zéro. Le -n dit de sortinger numériquement et le -k1 ne considère que le premier champ lors du sorting.
  • awk :
    • -vRS='\0' : réglez le séparateur d'logging d'input (ligne) sur \0 ;
    • vn=$1 : définissez la variable n sur tout ce qui a été donné en input à la fonction;
    • NR==n{} : exécutez ceci uniquement sur la ligne n (5 dans le premier exemple);
    • sub(/^[^ ]* /,"",$0); print sub(/^[^ ]* /,"",$0); print : remplacez tous les caractères non spatiaux depuis le début de la ligne ( ^[^ ]* ) jusqu'au premier espace et imprimez le résultat

Une façon de le faire (en supposant qu'aucune nouvelle ligne dans vos noms de file) serait

 ls -t ... | head -n5 | tail -n1 

Avec zsh :

 print -r -- *(.Dom[5]) 

vous donne le 5ème file dans le directory courant sortingé par time de m odification. Changez m en a pour sortinger par a time d'access. . et D n'incluent que des files réguliers et cachés.