bash 从 ls 输出中提取文件名和修改时间
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22712604/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extracting filename & modification time from ls output
提问by beginner_ansh
I have a set of files in a directory. I want to extract just the filename without the absolute path & the modification timestamp from the ls output.
我在一个目录中有一组文件。我只想从 ls 输出中提取没有绝对路径和修改时间戳的文件名。
/apps/dir/file1.txt
/apps/dir/file2.txt
now from the ls output i extract out the fields for filename & timestamp
现在从 ls 输出中我提取出文件名和时间戳的字段
ls -ltr /apps/dir | awk '{print }'
Sep 25 2013 /apps/dir/file1.txt
Dec 20 2013 /apps/dir/file2.txt
Dec 20 2013 /apps/dir/file3.txt
whereas i want it to be like
而我希望它像
Sep 25 2013 file1
Dec 20 2013 file2
Dec 20 2013 file3
one solution can be to cd to that directory and run the command from there, but is there a solution possible without cd? I also used substr() but since filenames are not of equal length so passing a constant value to substr() function didn't work out.
一种解决方案可以是 cd 到该目录并从那里运行命令,但是有没有没有 cd 的解决方案?我也使用了 substr() 但由于文件名的长度不同,因此将常量值传递给 substr() 函数不起作用。
回答by jaypal singh
With GNU
find, you can do the following to get the filenames without path:
使用GNU
find,您可以执行以下操作来获取没有路径的文件名:
find /apps/dir -type f -printf "%f\n"
and as Kojiromentioned in the comments, you can use %t
or %T(format)
to get modification time.
正如Kojiro在评论中提到的,您可以使用%t
或%T(format)
来获取修改时间。
or do as BroSlowsuggested
或者按照BroSlow 的建议去做
find /apps/dir -printf "%Ab %Ad %AY %f\n"
Do nottry to do the following (It will break on filenames with spaces and even across different OS where ls -l
representation has fewer/more columns:
不要尝试执行以下操作(它会在带有空格的文件名上中断,甚至在ls -l
表示具有更少/更多列的不同操作系统中也会中断:
ls -ltr /apps/dir | awk '{n=split(,f,/\//);print ,,,f[n]}'
回答by Timmah
Dontparse output of ls command, rather use stat:
不要解析 ls 命令的输出,而是使用 stat:
stat -c%y filename
This will print the last modification time in human readable format
这将以人类可读的格式打印上次修改时间
Or if using GNU date you could use date with a format parameter and the reference flag
或者,如果使用 GNU 日期,您可以使用带有格式参数和参考标志的日期
date '+%b %d %Y' -r filename
You can use basename to get just the filename portion of the path:
您可以使用 basename 来获取路径的文件名部分:
basename /path/to/filename
Or as Kojiro suggested with parameter expansion:
或者正如 Kojiro 建议的参数扩展:
To get just the filename:
只获取文件名:
filename="${filename##*/}"
And then to strip of extension, if any:
然后是带扩展名,如果有的话:
filename="${filename%.*}"
Putting it all together:
把它们放在一起:
#!/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
回答by Jayesh Bhoi
#!/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
回答by glenn Hymanman
If you want to reproduce the ls
time format:
如果要重现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
Assuming the GNU set of tools
假设使用 GNU 工具集