提取文件名&从ls输出修改时间

时间:2014-03-28 12:16:28

标签: linux bash shell awk

我在目录中有一组文件。我想在没有绝对路径的情况下提取文件名。来自ls输出的修改时间戳。

/apps/dir/file1.txt               
/apps/dir/file2.txt

现在从ls输出中我提取出文件名和字段的字段。时间戳

ls -ltr /apps/dir | awk '{print $6 $7 $8 $9}'

Sep  25  2013 /apps/dir/file1.txt  
Dec  20  2013 /apps/dir/file2.txt  
Dec  20  2013 /apps/dir/file3.txt

而我希望它像

Sep 25  2013 file1     
Dec 20  2013 file2  
Dec 20  2013 file3

一个解决方案可以是cd到那个目录并从那里运行命令,但有没有cd的解决方案?我也使用了substr(),但由于文件名的长度不相等,所以将常量值传递给substr()函数并没有用完。

4 个答案:

答案 0 :(得分:7)

使用GNU查找,您可以执行以下操作来获取没有路径的文件名:

find /apps/dir -type f -printf "%f\n"

以及评论中提到的Kojiro,您可以使用%t%T(format)来获取修改时间。

或按BroSlow建议

find /apps/dir -printf "%Ab %Ad %AY %f\n"

不要尝试执行以下操作(它会在包含空格的文件名中断,甚至在ls -l表示具有更少/更多列的不同操作系统中断:

ls -ltr /apps/dir | awk '{n=split($9,f,/\//);print $6,$7,$8,f[n]}'

答案 1 :(得分:2)

Dont解析ls命令的输出,而不是使用stat:

stat -c%y filename

这将以人类可读格式打印最后修改时间

或者如果使用GNU日期,您可以使用带格式参数的日期和参考标志

date '+%b %d %Y' -r filename

您可以使用basename来获取路径的文件名部分:

basename /path/to/filename

或者正如Kojiro建议parameter expansion

获取文件名:

filename="${filename##*/}"

然后剥离扩展,如果有的话:

filename="${filename%.*}"

全部放在一起:

#!/usr/bin/env bash

for filename in *; do
    timestamp=$(stat -c%y "$filename")
    #Uncomment below for a neater timestamp
    #timestamp="${timestamp%.*}"

    filename="${filename##*/}"
    filename="${filename%.*}"

    echo "$timestamp $filename"
done

答案 2 :(得分:0)

#!/bin/bash
files=$(find /apps/dir -maxdepth 1 -type f)
for i in $files; do
    file=$(basename $i)
    timestamp=$(stat -c%y $i)
    printf "%-50s %s\n" "$timestamp" "$file" 
done

答案 3 :(得分:0)

如果您想重现ls时间格式:

dir=/apps/dir
now=$(date +%s) 
sixmo=$(date -d '6 months ago' +%s)

find "$dir" -maxdepth 1 -print0 | 
while read -d '' -r filename; do 
    mtime=$(stat -c %Y "$filename") 
    if (( sixmo <= mtime && mtime <= now )); then 
        fmt="%b %d %H:%M"
    else 
        fmt="%b %d  %Y"
    fi
    printf "%12s %s\n" "$(date -d "@$mtime" "+$fmt")" "$(basename "$filename")"
done |
sort -k 4

假设GNU工具集