-1

我正在编写一个脚本来计算目录中最旧文件的年龄。运行的第一个命令是:

OLDFILE=`ls -lt $DIR | grep "^-" | tail -1 `    
echo $OLDFILE

输出包含的不仅仅是文件名。例如

-rwxrwxr-- 1 abc abc 334 May 10 2011 ABCD_xyz20110510113817046.abc.bak

第一季度/。如何在上述行的最后一个空格之后获得输出?这会给我文件名。我意识到需要某种字符串操作,但对 shell 脚本来说是新手。

Q2/。如何以分钟为单位获取此文件的年龄?

4

4 回答 4

1

要仅获取最旧文件的名称,

ls -lt | awk '/^-/{file=$NF}END{print file}'

但是,如果您的文件名称中有空格等,这并不可靠。通常,您应该尽量避免解析来自ls.

stat您可以获得机器可读格式的文件创建日期,以自 1970 年 1 月 1 日以来的秒数表示;与date +%s您可以以相同的格式获取当前时间。减去并除以 60。(更多的 Awk 技能会派上用场算术。)

最后,对于替代解决方案,请查看find; 特别是,它的printf格式字符串允许您提取文件的年龄。以下将直接为您提供最旧文件的以秒为单位的年龄和 inode 编号:

find . -maxdepth 1 -type f -printf '%T@ %i\n' |
sort -n | head -n 1

使用 inode 号避免了有趣的文件名问题;一旦你有一个 inode,将其转换为文件名是一件轻而易举的事:

find . -maxdepth 1 -inum "$number"

将两者结合在一起,你可能想要这样的东西:

# set -- Replace $@ with output from command
set -- $(find . -maxdepth 1 -type f -printf '%T@ %i\n' |
         sort -n | head -n 1)
# now $1 is the timestamp and $2 is the inode

oldest_filename=$(find . -maxdepth 1 -inum "$2")
age_in_minutes=$(date +%s | awk -v d="$1" '{ print ($1 - d) / 60 }')
于 2013-05-21T04:57:27.763 回答
0

你可能想要ls -t. 包括 '-l' 选项明确要求 ls 为您提供您真正想要摆脱的所有其他信息。但是,您可能真正想要的是首先找到:

NEWEST=$(find . -maxdepth 1 -type f | cut -c3- |xargs ls -t| head -1)

这将为您提供最新项目的纯文件名,无需其他处理。目录将被正确排除。(感谢 Tripleee 指出这就是您的目标。)

对于第二个问题,您可以使用 stat 和 bc:

TIME_MINUTES=$(stat --format %Y/60 "$NEWEST" |bc -l)

如果您只想要整数分钟,请从 bc 中删除“-l”选项。

于 2013-05-21T05:33:45.307 回答
0

一个awk解决方案,以分钟为单位为您提供文件的年龄(因为您的 ls 输出不包含创建的最小值,因此默认情况下假定为 00)。同样正如triplee 指出的那样,ls输出本身就存在被解析的风险。

[[bash_prompt$]]$ echo $l; echo "##############";echo $l | awk -f test.sh ; echo "#############"; cat test.sh
-rwxrwxr-- 1 abc abc 334 May 20 2013 ABCD_xyz20110510113817046.abc.bak
##############
File ABCD_xyz20110510113817046.abc.bak is 2074.67 min old
#############
BEGIN{
   m=split("Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec",d,"|")
   for(o=1;o<=m;o++){
      date[d[o]]=sprintf("%02d",o)
    }
}
{
month=date[$6];
old_time=mktime($8" "month" "$7" "00" "00" "00);
curr_time=systime();
print "File " $NF " is " (curr_time-old_time)/60 " min old";
}
于 2013-05-21T05:09:40.903 回答
0

For Q2 a bash one-liner could be:

let mtime_minutes=\(`date +%s`-`stat -c%Y "$file_to_inspect"`\)/60
于 2013-05-21T05:28:46.570 回答