Si j'ai modifié un fichier il y a 5 minutes, est-il possible de faire en sorte que la sortie de ls-l
affiche quelque chose comme "5 mins" au lieu de la date/heure actuelle ?
Réponses
Trop de publicités?J'utilise stat pour obtenir des informations métadonnées sur les fichiers. Voici quelques exemples :
stat -c $'%y\t%n' * | sort -n
La sortie ressemble à ceci :
2020-01-27 11:52:25.681249958 +0200 CHANGELOG.md
Ensuite, pour consulter un seul fichier
stat CHANGELOG.md
et la sortie ressemble à ceci :
Fichier : CHANGELOG.md
Taille : 94 Blocs : 8 Blocs d'E/S : 4096 fichier ordinaire
Périphérique : fd00h/64768d Inode : 6029378 Liens : 1
Accès : (0644/-rw-r--r--) Uid : ( 998/example) Gid : ( 998/example)
Accès : 2020-11-12 17:47:34.768793021 +0200
Modification : 2020-01-27 11:52:25.681249958 +0200
Changement : 2020-11-12 17:47:02.282093672 +0200
Création : -
Sinon, vous pourriez avoir besoin d'un petit script bash pour vous montrer la différence entre la création du fichier et l'heure actuelle.
DernièreMiseÀJour="$(stat -c %Y myfile)"
maintenant="$(date +%s)"
la différence=$((maintenant - dernièreMiseÀJour))
Ceci est une continuation d'un script précédent utilisé pour l'analyse
de ls -l
avec quelques améliorations :
#!/bin/bash
while read -r p c u g s e n; do
[[ $p = total ]] && { \
echo "$p $c" 1>&2; continue; \
}
x=$(($EPOCHSECONDS - e))
y=$((x / 60))
z=$((x % 60))
printf '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n' \
"$p" \
"$c" \
"$u" \
"$g" \
"$s" \
"$y minutes" \
"$z seconds" \
"$n"
done < <( \
ls -LApl --color=force \
--time-style=+%s \
--quoting-style=shell-escape "$@" \
) \
| column -t -R 2,5,6,7 -s $'\t' -o ' '
Une façon :
Vous pouvez faire en sorte que ls
affiche l'heure de modification en secondes depuis l'époque, comme ceci :
ls -l --time-style="+%s"
Ensuite, redirigez la sortie de ls
vers awk
pour effectuer la logique, comme ceci :
ls -l --time-style="+%s" | awk -v now=$(date +%s) '{$6 = now - $6; d=int($6/60/60/24); h=int($6/60/60%24); m=int($6/60%60); s=int($6%60);$6 = "="d" jours "h" heures "m" minutes "s" secondes auparavant="; print}' | column -t -s'='
Étant donné que la ligne de commande est longue, voici une séparation qui est essentiellement la même mais peut être visuellement plus contenue :
ls -l --time-style="+%s" | \
awk -v now=$(date +%s) '{\
$6 = now - $6; \
d=int($6/60/60/24); \
h=int($6/60/60%24); \
m=int($6/60%60); \
s=int($6%60);\
$6 = "="d" jours "h" heures "m" minutes "s" secondes auparavant="; print}' | column -t -s'='
-
-v now=$(date +%s)
assignera l'heure actuelle en secondes depuis l'époque ànow
-
$6 = now - $6
calculera le temps en secondes depuis la dernière modification du fichier. -
d=int($6/60/60/24)
calculera les jours. -
h=int($6/60/60%24)
calculera les heures restantes en-dessous d'une journée. -
m=int($6/60%60)
calculera les minutes restantes en-dessous d'une heure. -
s=int($6%60)
calculera les secondes restantes en-dessous d'une minute. -
$6 = d" jours "h" heures "m" minutes "s" secondes auparavant"
changera la date de modification en quelque chose comme 2 jours 5 heures 3 minutes 47 secondes auparavant.
Une autre façon :
Vous pouvez construire votre propre alternative personnalisée à ls -l
dans un script bash, comme ceci :
#!/bin/bash
for f in *
do
p=$(stat -c "%A=%h=%U=%G=%s" "$f")
m=$(date -r "$f" "+%s")
n=$(date "+%s")
l=$((n-m))
d=$((l/60/60/24))
h=$((l/60/60%24))
m=$((l/60%60))
s=$((l%60))
echo "$p= = =$d jours=$h heures=$m minutes=$s=secondes= = =$f" | column -t -s'='
done
ou simplifiez la sortie et soyez moins rigide en termes de temps, comme ceci :
#!/bin/bash
for f in *
do
p=$(stat -c "%A %h %U %G %s" "$f")
m=$(date -r "$f" "+%s")
n=$(date "+%s")
l=$((n-m))
d=$((l/60/60/24))
h=$((l/60/60%24))
m=$((l/60%60))
s=$((l%60))
if (( $d >= 1 ))
then
t="$d jours"
elif (( $h >= 1 ))
then
t="$h heures"
elif (( $m >= 1 ))
then
t="$m minutes"
else
t="$s secondes"
fi
echo "$p= = =$t= = =$f" | column -t -s'='
done
Remarque sur l'utilisation :
Si vous enregistrez une des deux commandes ci-dessus ou le script ci-dessus dans un fichier de votre répertoire personnel, nommez le fichier lsl.sh
et rendez-le exécutable comme ceci :
chmod +x ~/lsl.sh
vous pouvez ajouter un alias comme ceci :
alias lsl='bash ~/lsl.sh'
dans votre fichier ~/.bashrc
pour ensuite exécuter la commande abrégée : `
lsl
de n'importe quel répertoire et obtenir le résultat souhaité.
Répondre à ma propre question ici car c'est ce que j'ai finalement fait.
Je n'ai pas obtenu de résultats satisfaisants en utilisant quoi que ce soit qui analysait la sortie de ls -l
en un flux de mots (bash
, awk
, column
, etc.) car a) les noms de fichiers avec des espaces dans le désordre, et b) les colonnes alignées de ls -l
étaient en désordre (par exemple, les tailles de fichiers alignées à droite). ls -l | column -t
montre les deux problèmes à la fois.
Je serai critiqué pour l'inefficacité de cela, mais voici finalement mon script qui utilise sed
pour remplacer des parties de la sortie de ls -l
en conservant la largeur des colonnes:
day0=`date +"%b %_d"`
day1=`date --date "1 day ago" +"%b %_d"`
day2=`date --date "2 days ago" +"%b %_d"`
day3=`date --date "3 days ago" +"%b %_d"`
day4=`date --date "4 days ago" +"%b %_d"`
day5=`date --date "5 days ago" +"%b %_d"`
day6=`date --date "6 days ago" +"%b %_d"`
min0=`date +"%H:%M"`
min1=`date --date "1 minute ago" +"%H:%M"`
min2=`date --date "2 minutes ago" +"%H:%M"`
min3=`date --date "3 minutes ago" +"%H:%M"`
min4=`date --date "4 minutes ago" +"%H:%M"`
min5=`date --date "5 minutes ago" +"%H:%M"`
min6=`date --date "6 minutes ago" +"%H:%M"`
min7=`date --date "7 minutes ago" +"%H:%M"`
min8=`date --date "8 minutes ago" +"%H:%M"`
min9=`date --date "9 minutes ago" +"%H:%M"`
ls -lh --color=force --quoting-style=shell-escape "$@"|sed "\
/$day6 \(.[0-9]:[0-9][0-9]\)/ s/$day6/6 jours/; t
/$day5 \(.[0-9]:[0-9][0-9]\)/ s/$day5/5 jours/; t
/$day4 \(.[0-9]:[0-9][0-9]\)/ s/$day4/4 jours/; t
/$day3 \(.[0-9]:[0-9][0-9]\)/ s/$day3/3 jours/; t
/$day2 \(.[0-9]:[0-9][0-9]\)/ s/$day2/2 jours/; t
/$day1 \(.[0-9]:[0-9][0-9]\)/ s/$day1/hier/; t
/$day0 \(.[0-9]:[0-9][0-9]\)/ s/$day0/ aujourd'hui/; T
s/$min0/ maintenant/; t
s/$min1/1 min/; t
s/$min2/2 min/; t
s/$min3/3 min/; t
s/$min4/4 min/; t
s/$min5/5 min/; t
s/$min6/6 min/; t
s/$min7/7 min/; t
s/$min8/8 min/; t
s/$min9/9 min/; t
"
Exemple de sortie de /var/log/syslog*
:
-rw-r----- 1 syslog adm 9240 aujourd'hui maintenant /var/log/syslog
-rw-r----- 1 syslog adm 1279965 aujourd'hui 8 min /var/log/syslog.1
-rw-r----- 1 syslog adm 51750 2 jours 14:12 /var/log/syslog.2.gz
-rw-r----- 1 syslog adm 14768 3 jours 10:59 /var/log/syslog.3.gz
-rw-r----- 1 syslog adm 7767 4 jours 10:04 /var/log/syslog.4.gz
-rw-r----- 1 syslog adm 119295 5 jours 09:49 /var/log/syslog.5.gz
-rw-r----- 1 syslog adm 33450 6 jours 13:06 /var/log/syslog.6.gz
-rw-r----- 1 syslog adm 21372 janv. 25 11:12 /var/log/syslog.7.gz
(pas sûr pourquoi le log apparaît en rouge ici ; ce n'est pas le cas sur mon terminal).
Ceci est utilisé uniquement en ligne de commande donc tous ces commandes date
n'ont pas d'importance, en fait je ne remarque aucun délai du tout.
Mise à jour:
Sortie de time
pour `ls -l /var/log/syslog*':
réel 0m0.002s
utilisateur 0m0.002s
système 0m0.000s
Sortie de time
pour mon nouveau script:
réel 0m0.019s
utilisateur 0m0.018s
système 0m0.003s