`ls -l` 输出持续时间而不是日期/时间,例如“5 分钟”/“6 小时”/“7 天”等?

`ls -l` 输出持续时间而不是日期/时间,例如“5 分钟”/“6 小时”/“7 天”等?

如果我最后一次修改文件是在 5 分钟前,是否可以输出ls-l“5 分钟”之类的内容而不是实际的日期/时间?

答案1

我使用 stat 获取文件的元数据信息。以下是一些示例:

stat -c $'%y\t%n' * | sort -n

输出如下所示:

2020-01-27 11:52:25.681249958 +0200 CHANGELOG.md

然后查找单个文件

stat CHANGELOG.md

输出如下:

  File: CHANGELOG.md
  Size: 94          Blocks: 8          IO Block: 4096   regular file
  Device: fd00h/64768d  Inode: 6029378     Links: 1
  Access: (0644/-rw-r--r--)  Uid: (  998/example)   Gid: (  998/example)
  Access: 2020-11-12 17:47:34.768793021 +0200
  Modify: 2020-01-27 11:52:25.681249958 +0200
  Change: 2020-11-12 17:47:02.282093672 +0200
  Birth: -

否则,您可能需要一个小型的 bash 脚本来显示文件创建时间和当前时间之间的差异。

 LastUpdate="$(stat -c %Y myfile)"
 now="$(date +%s)"
 let diff="${now}-${lastUpdate}"

答案2

这是之前脚本用于解析
ls -l并进行一些增强:

#!/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 ' '

答案3

单程:

您可以ls以纪元以来的秒数打印修改时间,如下所示:

ls -l --time-style="+%s"

然后将ls输出通过管道传输到awk执行逻辑,如下所示:

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" Days "h" Hours "m" Mins "s" Secs ago="; print}' | column -t -s'='

由于命令行很长,下面是一个基本相同但在视觉上更加简洁的分解:

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" Days "h" Hours "m" Mins "s" Secs ago="; print}' | column -t -s'='
  • -v now=$(date +%s)将以纪元以来的秒数计算当前时间分配给now

  • $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" Days "h" Hours "m" Mins "s" Secs ago"将修改日期更改为类似2 天 5 小时 3 分钟 47 秒前


其他方式:

ls -l您可以在 Bash 脚本中构建自己的自定义替代方案,如下所示:

#!/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 Days=$h Hours=$m Mins=$s=Secs= = =$f" | column -t -s'='
        done

或者使输出更简单,时间限制更少,如下所示:

#!/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 Days"
        elif (( $h >= 1 ))
                then
                t="$h Hours"
        elif (( $m >= 1 ))
                then
                t="$m Mins"
        else
                t="$s Secs"
        fi 
        echo "$p= = =$t= = =$f" | column -t -s'='
        done

使用须知:

如果你保存任何一个上述命令或者上述脚本位于你的文件中主目录,命名文件lsl.sh并使其可执行,如下所示:

chmod +x ~/lsl.sh

您可以像这样添加别名:

alias lsl='bash ~/lsl.sh'

到你的~/.bashrc文件中,以便你随后可以运行简短的命令:`

lsl

从任何目录并获得所需的结果。

答案4

在这里回答我自己的问题,因为这正是我最终真正做的事情。

我无法使用任何将 的输出解析ls -l为字流(bashawkcolumn)的东西来获得任何令人满意的结果,因为 a) 中的空格混乱了,并且 b)ls -l的对齐列混乱了(例如,右对齐的文件大小)。ls -l | column -t同时显示两个问题。

我会因为其中的低效率而被击落,但这是我最终用来替换维护列宽sed的输出部分的脚本:ls -l

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 days/; t
  /$day5 \(.[0-9]:[0-9][0-9]\)/ s/$day5/5 days/; t
  /$day4 \(.[0-9]:[0-9][0-9]\)/ s/$day4/4 days/; t
  /$day3 \(.[0-9]:[0-9][0-9]\)/ s/$day3/3 days/; t
  /$day2 \(.[0-9]:[0-9][0-9]\)/ s/$day2/2 days/; t
  /$day1 \(.[0-9]:[0-9][0-9]\)/ s/$day1/yesday/; t
  /$day0 \(.[0-9]:[0-9][0-9]\)/ s/$day0/ today/; T
  s/$min0/  now/; 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
  "

输出样例/var/log/syslog*

-rw-r----- 1 syslog adm    9240  today   now /var/log/syslog
-rw-r----- 1 syslog adm 1279965  today 8 min /var/log/syslog.1
-rw-r----- 1 syslog adm   51750 2 days 14:12 /var/log/syslog.2.gz
-rw-r----- 1 syslog adm   14768 3 days 10:59 /var/log/syslog.3.gz
-rw-r----- 1 syslog adm    7767 4 days 10:04 /var/log/syslog.4.gz
-rw-r----- 1 syslog adm  119295 5 days 09:49 /var/log/syslog.5.gz
-rw-r----- 1 syslog adm   33450 6 days 13:06 /var/log/syslog.6.gz
-rw-r----- 1 syslog adm   21372 Jan 25 11:12 /var/log/syslog.7.gz

(不确定为什么日志在这里以红色出现;它没有出现在我的终端上。)

这仅从命令行使用,因此所有这些date命令都不重要,事实上我根本没有注意到任何延迟。

更新:

time‘ls -l /var/log/syslog*’ 的输出:

real    0m0.002s
user    0m0.002s
sys     0m0.000s

time我的新脚本的输出:

real    0m0.019s
user    0m0.018s
sys     0m0.003s

相关内容