将最新文件放在Linux上的目录中

ack*_*ack 154 linux command-line

寻找将返回目录中单个最新文件的命令.

没有看到ls的限制参数...

dmc*_*kee 227

ls -Art | tail -n 1
Run Code Online (Sandbox Code Playgroud)

不是很优雅,但它的工作原理.

  • 一个小问题:这个版本将`ls`的所有输出都传递给`tail`,然后只打印LAST行.恕我直言,最好按升序排序并使用`head`代替,因为`chaos`建议.打印完第一行后退出,所以发送下一行(实际上是下一个块)将上升一个SIGPIPE并且`ls`也将退出. (10认同)
  • 使用 ls -Artls 您还可以查看文件日期。 (7认同)
  • 我认为使用 tail 而不是 head 的预期好处可能是排除包含描述 ls 返回的总数的行。 (4认同)
  • @TrueY 我非常同意。混沌的答案对效率更好。 (3认同)
  • 请注意,此解决方案包括目录和文件。这可能是好事或坏事;这取决于个人用户的需求。我提出这个问题的原因是原始问题是“文件”。 (2认同)

cha*_*aos 125

ls -t | head -n1
Run Code Online (Sandbox Code Playgroud)

此命令实际上在当前工作目录中提供最新修改的文​​件.

  • @Josir可以修改它以包含带有`ls -tl |的日期戳 head -n 1`,它不必按照我的方式将整个桌子推过管道. (4认同)
  • 如果文件夹是最新修改过的,则返回一个文件夹,使用:`ls -Art | 如果您特别想要最新修改的文​​件,请转到-n1` (4认同)
  • 与我的相当,而且可能更有效。 (2认同)
  • @noɥʇʎԀʎzɐɹƆ `ls -t *.png | 头-n1` (2认同)

gio*_*ele 69

这是一个递归版本(即它在某个目录或其任何子目录中找到最近更新的文件)

find $DIR -type f -printf "%T@ %p\n" | sort -n | cut -d' ' -f 2- | tail -n 1
Run Code Online (Sandbox Code Playgroud)

编辑:使用-f 2-而不是-f 2凯文建议

  • 这是Mac的解决方案:`find $ DIR -type f -exec stat -lt"%Y-%m-%d"{}\+ | 切-d'' - f6- | sort -n | 尾巴-1` (5认同)
  • @user 的 Mac 版本仅排序/显示日期,而不是时间。这是一个固定版本:`find $DIR -type f -exec stat -lt "%F %T" {} \+ | 切 -d' ' -f6- | 排序 -n | 尾巴-1` (3认同)
  • 问题是cut命令截断带空格的路径而不是-f 2使用-f2-将字段2返回到行尾 (2认同)
  • 就像混乱中的建议一样,如果通过使用sort -nr反转排序,则可以使用head -n 1代替tail -n 1来稍微提高效率。(尽管如果要对递归查找进行排序,那么获取第一行或最后一行将不是很慢的部分。) (2认同)
  • 很有用!我发现如果通过管道连接到ls会更友好:`find ./ -type f -printf“%T @%p \ n” -ls | 排序-n | 切-d''-f 2- | 尾-n 1 | xargs -r ls -lah` (2认同)

小智 9

我用:

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

它只给我文件名,不包括文件夹.

  • 除非一个目录只有目录 (2认同)

Jar*_*aus 7

ls -lAtr | tail -1

其他解决方案不包含以...开头的文件'.'.

此命令还将包括'.''..',可能是您想要的,也可能不是:

ls -latr | tail -1


Pat*_*ick 7

查找/排序解决方案非常有效,直到文件数量变得非常大(就像整个文件系统一样)。改用 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]* //'
Run Code Online (Sandbox Code Playgroud)


Mik*_*keB 6

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

  • 命令是“回声”;它只是评估它的参数并将它们发送到标准输出。在这种情况下,glob 限定符“om[1]”有“o”,这意味着按照“m”(修改时间)对匹配文件进行排序。从那个有序列表中,取 [1],它是第一个文件。您可以阅读有关 glob 限定符的信息:http://zsh.sourceforge.net/Doc/Release/Expansion.html#Glob-Qualifiers (3认同)

Tru*_*ueY 6

我个人更喜欢使用尽可能少的非内置bash命令(以减少昂贵的 fork 和 exec 系统调用的数量)。ls按需要调用的日期排序。但使用 ofhead并不是真正必要的。我使用以下单行代码(仅适用于支持名称管道的系统):

read newest < <(ls -t *.log)
Run Code Online (Sandbox Code Playgroud)

或获取最旧文件的名称

read oldest < <(ls -rt *.log)
Run Code Online (Sandbox Code Playgroud)

(注意两个“<”标记之间的空格!)

如果还需要隐藏文件 -A arg 可以添加。

我希望这能有所帮助。

  • 假设您知道内置是什么,那么您可能是正确的。但是,我只是在考虑OP的问题。他们要求一个会返回一些东西的命令。从技术上讲,您的解决方案不会输出任何内容。所以只需添加“&amp;&amp; echo $newest”或类似的结尾;-) (4认同)

Dmy*_*nko 6

基于dmckee答案的简短变体:

ls -t | head -1
Run Code Online (Sandbox Code Playgroud)

  • 但是 head 的 `-1` 语法很久以前就已经被弃用了,应该使用 `-n 1` 。 (2认同)

Ste*_*las 5

有关可靠性的说明:

由于换行符是有效的任何一个文件名,它依赖于任何解决方案线head/ tail基础的人都是有缺陷的。

对于GNU ls,另一种选择是使用--quoting-style=shell-always选项和一个bash数组:

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

(如果您还想考虑隐藏文件,请添加该-A选项ls)。

如果要限制使用常规文件(忽略目录,fifos,设备,符号链接,套接字...),则需要使用GNU find

对于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]}"
Run Code Online (Sandbox Code Playgroud)

或递归地:

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

最好的办法是使用zsh及其限定符而不是bash避免所有这些麻烦:

当前目录中的最新常规文件:

printf '%s\n' *(.om[1])
Run Code Online (Sandbox Code Playgroud)

包括隐藏的:

printf '%s\n' *(D.om[1])
Run Code Online (Sandbox Code Playgroud)

第二最新:

printf '%s\n' *(.om[2])
Run Code Online (Sandbox Code Playgroud)

解析符号链接后检查文件年龄:

printf '%s\n' *(-.om[1])
Run Code Online (Sandbox Code Playgroud)

递归地:

printf '%s\n' **/*(.om[1])
Run Code Online (Sandbox Code Playgroud)

同样,compinit启用了完成系统(和co)后,它Ctrl+Xm会成为扩展程序,扩展为最新文件。

所以:

Ctrl+Xm

使您可以编辑最新文件(在按之前,您还可以查看它Return)。

Alt+2Ctrl+Xm

对于第二最新的文件。

vi * .cCtrl+Xm

获取最新c文件。

vi *(。)Ctrl+Xm

以获取最新的常规文件(不是目录,也不是fifo / device ...),依此类推。

  • @SergioAraujo,“c”就像“find”的“-ctime”一样,用于*inode更改时间*,与*创建*时间无关。“mtime”可以被视为文件内容的创建时间(因为这些内容永远不会一次性创建)。某些系统和文件系统记录*诞生*/*创建*时间,即文件的 inode 生成(可能*再次*)存在的时间,但没有可移植的 API 来检索该时间,并且 zsh 还没有相应的排序限定符。但那个特定的时间并不是特别有用。请参阅[文件创建时间](//unix.stackexchange.com/a/119699) (2认同)

OAS*_*mbH 5

如果您想获取最新更改的文件,还包括任何子目录,您可以使用这个小小的 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
Run Code Online (Sandbox Code Playgroud)

如果您不想对更改的文件执行相同操作,而是对访问的文件执行相同操作,则只需更改

%Y参数从stat命令到%X。您最近访问的文件的命令如下所示:

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
Run Code Online (Sandbox Code Playgroud)

对于这两个命令,如果您想列出多个文件,您还可以更改var="1"参数。