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
可以避免使用 sed
和 tail -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" 错误。)
我在一个文件夹中有一堆日志文件。当我进入文件夹并查看文件时,它看起来像这样。
$ 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
可以避免使用 sed
和 tail -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" 错误。)