简体   繁体   English

获取 Linux 目录中的最新文件

[英]Get most recent file in a directory on Linux

Looking for a command that will return the single most recent file in a directory.寻找将返回目录中单个最新文件的命令。

Not seeing a limit parameter to ls ...没有看到ls的限制参数...

ls -Art | tail -n 1

不是很优雅,但它有效。

ls -t | head -n1

该命令实际上给出了当前工作目录中最新修改的文​​件。

This is a recursive version (ie it finds the most recently updated file in a certain directory or any of its subdirectory)这是一个递归版本(即它在某个目录或其任何子目录中找到最近更新的文件)

find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1

Edit: use -f 2- instead of -f 2 as suggested by Kevin编辑:按照凯文的建议使用-f 2-而不是-f 2

A note about reliability:关于可靠性的说明:

Since the newline character is as valid as any in a file name, any solution that relies on lines like the head / tail based ones are flawed.由于换行符与文件名中的任何字符一样有效,因此任何依赖于基于head / tail行的解决方案都是有缺陷的。

With GNU ls , another option is to use the --quoting-style=shell-always option and a bash array:对于 GNU ls ,另一种选择是使用--quoting-style=shell-always选项和一个bash数组:

eval "files=($(ls -t --quoting-style=shell-always))"
((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

(add the -A option to ls if you also want to consider hidden files). (如果您还想考虑隐藏文件,请将-A选项添加到ls )。

If you want to limit to regular files (disregard directories, fifos, devices, symlinks, sockets...), you'd need to resort to GNU find .如果您想限制为常规文件(忽略目录、fifos、设备、符号链接、套接字...),您需要求助于 GNU find

With bash 4.4 or newer (for readarray -d ) and GNU coreutils 8.25 or newer (for cut -z ):使用 bash 4.4 或更高版本(对于readarray -d )和 GNU coreutils 8.25 或更高版本(对于cut -z ):

readarray -t -d '' files < <(
  LC_ALL=C find . -maxdepth 1 -type f ! -name '.*' -printf '%T@/%f\0' |
  sort -rzn | cut -zd/ -f2)

((${#files[@]} > 0)) && printf '%s\n' "${files[0]}"

Or recursively:或者递归:

readarray -t -d '' files < <(
  LC_ALL=C find . -name . -o -name '.*' -prune -o -type f -printf '%T@%p\0' |
  sort -rzn | cut -zd/ -f2-)

Best here would be to use zsh and its glob qualifiers instead of bash to avoid all this hassle:这里最好是使用zsh和它的 glob 限定符而不是bash来避免所有这些麻烦:

Newest regular file in the current directory:当前目录中最新的常规文件:

printf '%s\n' *(.om[1])

Including hidden ones:包括隐藏的:

printf '%s\n' *(D.om[1])

Second newest:第二个最新:

printf '%s\n' *(.om[2])

Check file age after symlink resolution:在符号链接解析后检查文件年龄:

printf '%s\n' *(-.om[1])

Recursively:递归地:

printf '%s\n' **/*(.om[1])

Also, with the completion system ( compinit and co) enabled, Ctrl+X m becomes a completer that expands to the newest file.此外,启用完成系统( compinit和 co)后, Ctrl+X m成为扩展到最新文件的完成器。

So:所以:

vi Ctrl+Xm

Would make you edit the newest file (you also get a chance to see which it before you press Return ).会让你编辑最新的文件(你也有机会在按下Return之前看到它)。

vi Alt+2Ctrl+Xm

For the second-newest file.对于第二个最新的文件。

vi *.cCtrl+Xm

for the newest c file.对于最新的c文件。

vi *(.)Ctrl+Xm

for the newest regular file (not directory, nor fifo/device...), and so on.对于最新的常规文件(不是目录,也不是 fifo/device...),依此类推。

I use:我用:

ls -ABrt1 --group-directories-first | tail -n1

It gives me just the file name, excluding folders.它只给我文件名,不包括文件夹。

ls -lAtr | tail -1

The other solutions do not include files that start with '.'其他解决方案不包括以'.'开头的文件'.' . .

This command will also include '.'此命令还将包含'.' and '..' , which may or may not be what you want:'..' ,这可能是也可能不是你想要的:

ls -latr | tail -1

The find / sort solution works great until the number of files gets really large (like an entire file system).查找/排序解决方案非常有效,直到文件数量变得非常大(就像整个文件系统一样)。 Use awk instead to just keep track of the most recent file:改用 awk 来跟踪最新的文件:

find $DIR -type f -printf "%T@ %p\n" | 
awk '
BEGIN { recent = 0; file = "" }
{
if ($1 > recent)
   {
   recent = $1;
   file = $0;
   }
}
END { print file; }' |
sed 's/^[0-9]*\.[0-9]* //'

基于 dmckee 的回答的短路变体:

ls -t | head -1

我喜欢echo *(om[1])zsh语法),因为zsh给出文件名而不调用任何其他命令。

If you want to get the most recent changed file also including any subdirectories you can do it with this little oneliner:如果您想获取最新更改的文件,还包括任何子目录,您可以使用这个小小的 oneliner 来完成:

find . -type f -exec stat -c '%Y %n' {} \; | sort -nr | awk -v var="1" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done

If you want to do the same not for changed files, but for accessed files you simple have to change the如果您不想对更改的文件执行相同操作,而是对访问的文件执行相同操作,则只需更改

%Y parameter from the stat command to %X . %Y参数从stat命令到%X And your command for most recent accessed files looks like this:您最近访问的文件的命令如下所示:

find . -type f -exec stat -c '%X %n' {} \; | sort -nr | awk -v var="1" 'NR==1,NR==var {print $0}' | while read t f; do d=$(date -d @$t "+%b %d %T %Y"); echo "$d -- $f"; done

For both commands you also can change the var="1" parameter if you want to list more than just one file.对于这两个命令,如果您想列出多个文件,您还可以更改var="1"参数。

I personally prefer to use as few not built-in bash commands as I can (to reduce the number of expensive fork and exec syscalls).我个人更喜欢尽可能少地使用非内置bash命令(以减少昂贵的 fork 和 exec 系统调用的数量)。 To sort by date the ls needed to be called.要按日期排序,需要调用ls But using of head is not really necessary.但是使用head并不是真正必要的。 I use the following one-liner (works only on systems supporting name pipes):我使用以下单行(仅适用于支持名称管道的系统):

read newest < <(ls -t *.log)

or to get the name of the oldest file或获取最旧文件的名称

read oldest < <(ls -rt *.log)

(Mind the space between the two '<' marks!) (注意两个 '<' 标记之间的空格!)

If the hidden files are also needed -A arg could be added.如果还需要隐藏文件 - 可以添加 arg。

I hope this could help.我希望这会有所帮助。

使用 R 递归选项 .. 您可以将其视为此处的好答案的增强

ls -arRtlh | tail -50

With only Bash builtins, closely following BashFAQ/003 :只有 Bash 内置函数,紧跟BashFAQ/003

shopt -s nullglob

for f in * .*; do
    [[ -d $f ]] && continue
    [[ $f -nt $latest ]] && latest=$f
done

printf '%s\n' "$latest"

try this simple command试试这个简单的命令

ls -ltq  <path>  | head -n 1

If you want file name - last modified, path = /ab/cd/*.log如果你想要文件名 - 最后修改,路径 = /ab/cd/*.log

If you want directory name - last modified, path = /ab/cd/*/如果你想要目录名 - 最后修改,路径 = /ab/cd/*/

ls -t -1 | sed '1q'

Will show the last modified item in the folder.将显示文件夹中最后修改的项目。 Pair with grep to find latest entries with keywordsgrep配对以查找带有关键字的最新条目

ls -t -1 | grep foo | sed '1q'

递归地:

find $1 -type f -exec stat --format '%Y :%y %n' "{}" \; | sort -nr | cut -d: -f2- | head

Presuming you don't care about hidden files that start with a .假设您不关心以.

ls -rt | tail -n 1

Otherwise否则

ls -Art | tail -n 1
ls -Frt | grep "[^/]$" | tail -n 1

All those ls/tail solutions work perfectly fine for files in a directory - ignoring subdirectories.所有这些 ls/tail 解决方案都适用于目录中文件 - 忽略子目录。

In order to include all files in your search (recursively), find can be used.为了在搜索中包含所有文件(递归),可以使用 find 。 gioele suggested sorting the formatted find output. gioele 建议对格式化的查找输出进行排序。 But be careful with whitespaces (his suggestion doesn't work with whitespaces).但是要小心空格(他的建议不适用于空格)。

This should work with all file names:这应该适用于所有文件名:

find $DIR -type f -printf "%T@ %p\n" | sort -n | sed -r 's/^[0-9.]+\s+//' | tail -n 1 | xargs -I{} ls -l "{}"

This sorts by mtime, see man find:这按 mtime 排序,请参阅 man find:

%Ak    File's  last  access  time in the format specified by k, which is either `@' or a directive for the C `strftime' function.  The possible values for k are listed below; some of them might not be available on all systems, due to differences in `strftime' between systems.
       @      seconds since Jan. 1, 1970, 00:00 GMT, with fractional part.
%Ck    File's last status change time in the format specified by k, which is the same as for %A.
%Tk    File's last modification time in the format specified by k, which is the same as for %A.

So just replace %T with %C to sort by ctime.所以只需用%C替换%T即可按 ctime 排序。

根据模式查找每个目录中的最新文件,例如工作目录的子目录名称以“tmp”结尾(不区分大小写):

find . -iname \*tmp -type d -exec sh -c "ls -lArt {} | tail -n 1" \;

Find the file with prefix of shravan* and view查找前缀为shravan*的文件并查看

less $(ls -Art shravan* | tail -n 1)

If you want to find the last modified folder name within /apps/test directory then you can put below code snippet in a batch script and execute it which will print the name of the last modified folder name.如果你想在 /apps/test 目录中找到最后修改的文件夹名称,那么你可以将下面的代码片段放在批处理脚本中并执行它,这将打印最后修改的文件夹名称的名称。

#!/bin/bash -e

export latestModifiedFolderName=$(ls -td /apps/test/*/ | head -n1)

echo Latest modified folder within /apps/test directory is $latestModifiedFolderName

I needed to do it too, and I found these commands.我也需要这样做,我找到了这些命令。 these work for me:这些对我有用:

If you want last file by its date of creation in folder(access time) :如果您希望按文件夹中的创建日期(访问时间)显示最后一个文件:

ls -Aru | tail -n 1  

And if you want last file that has changes in its content (modify time) :如果您想要内容发生变化的最后一个文件(修改时间):

ls -Art | tail -n 1  

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM