如果我最后一次修改文件是在 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
为字流(bash
、awk
等column
)的东西来获得任何令人满意的结果,因为 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