bash tail 文件夹中的最新文件没有变量

bash tail the newest file in folder without variable

我在一个文件夹中有一堆日志文件。当我进入文件夹并查看文件时,它看起来像这样。

$ ls -lhat
-rw-r--r--   1 root root 5.3K Sep 10 12:22 some_log_c48b72e8.log
-rw-r--r--   1 root root 5.1M Sep 10 02:51 some_log_cebb6a28.log
-rw-r--r--   1 root root 1.1K Aug 25 14:21 some_log_edc96130.log
-rw-r--r--   1 root root 406K Aug 25 14:18 some_log_595c9c50.log
-rw-r--r--   1 root root  65K Aug 24 16:00 some_log_36d179b3.log
-rw-r--r--   1 root root  87K Aug 24 13:48 some_log_b29eb255.log
-rw-r--r--   1 root root  13M Aug 22 11:55 some_log_eae54d84.log
-rw-r--r--   1 root root 1.8M Aug 12 12:21 some_log_1aef4137.log

我想查看最新日志文件中的最新消息。我现在可以手动复制最新日志的名称,然后对其执行尾部操作,这样就可以了。

$ tail -n 100 some_log_c48b72e8.log 

这确实涉及体力劳动,因此我想使用 bash-fu 来完成此操作。

我目前找到了这种方法;

filename="$(ls -lat | sed -n 2p |  tail -c 30)"; tail -n 100 $filename

它有效,但我很沮丧,因为我需要将数据保存到变量中才能执行此操作。是否可以在 bash 中执行此操作而不将中间结果保存到变量中?

tail -n 100 "$(ls -at | head -n 1)"

您不需要 ls 实际 打印 时间戳,您只需要按它们排序 (ls -t)。我添加了 -a 选项,因为它在您的原始代码中,但请注意,这不是必需的,除非您的日志文件是 "dot files",即以 . 开头(它们不应该) .

以这种方式使用 ls 可以避免使用 sedtail -c 解析输出。 (并且 you should not try to parse the output of ls。)只需选择列表中的第一个文件 (head -n 1),这是最新的。将它放在引号中应该可以避免文件名中更常见的 "problems" 之类的空格。 (如果您的文件名中有换行符或类似内容,修复您的文件名。:-D)

您可以就地使用命令替换,而不是保存到变量中。

你也可以这样试试

ls -1t  | head -n 1  | xargs tail -c 50

解释:

ls   -1rht     -- list the files based on modified time in reverse order.
tail -n 1      -- get the last one file 
tail -c 50     -- show the last 50 character from the file.

如果不解析 ls,您将使用 stat

tail -n 100 "$(stat -c "%Y %n" * | sort -nk1,1 | tail -1 | cut -d" " -f 2-)"

如果您的文件名包含换行符,将会中断。


版本 2:可以换行

tail -n 100 "$(
    stat --printf "%Y:%n[=11=]" * | 
    sort -z -t: -k1,1nr | 
    { IFS=: read -d '' time filename; echo "$filename"; }
)"

一个真正 ls 免费的解决方案:

tail -n 100 < <(
  for f in *; do
    [[ $f -nt $newest ]] && newest=$f
  done
  cat "$newest"
  )

不需要初始化newest,因为任何文件都会比空字符串命名的空文件更新。

它有点冗长,但它保证适用于任何合法的文件名。将其保存到 shell 函数以便于使用:

tail_latest () {
  dir=${1:-.}
  size=${2:-100}
  for f in "$dir"/*; do
      [[ $f -nt $newest ]] && newest=$f
  done
  tail -f "$size" "$newest"
}

一些例子:

# Default of 100 lines from newest file in the current directory
tail_latest
# 200 lines from the newest file in another directory
tail_latest /some/log/dir 200

zsh 插件:glob 限定符可让您直接对 glob 的结果进行排序,从而更容易获得最新文件。

tail -n 100 *(om[1,1])

om 按修改时间对结果进行排序(最新的在前)。 [1,1] 限制与第一个匹配的文件范围。 (我认为 Y1 应该做同样的事情,但它一直给我一个 "unknown file attribute" 错误。)