检查文件是否存在,获取最新的文件

检查文件是否存在,获取最新的文件

如果我的test文件夹中有这些文件

ehsant@lp02944:~/test$ll
total 24
drwxr-xr-x 2 ehsant ehsant 4096 May 19 17:54 .
drwxr-xr-x 6 ehsant ehsant 4096 May 19 14:45 ..
-rw-r--r-- 1 ehsant ehsant    7 May 19 14:53 log.20200519_04
-rw-r--r-- 1 ehsant ehsant    7 May 19 14:54 log.20200519_05
-rw-r--r-- 1 ehsant ehsant    8 May 19 14:55 log.20200519_06
-rw-r--r-- 1 ehsant ehsant    7 May 19 14:56 log.20200519_07

假设当前日期为 2020/05/19

我如何在最近的文件中搜索特定单词?根据log.20200519_07 我的要求,bash 命令只能在一行中。我必须首先检查是否存在这种格式的文件log.$(date +%Y%m%d)_?? ,如果找到,则在最近的文件中进行搜索。

有不同的场景:

1- 文件夹中没有文件 -> 然后不执行任何操作
2- 文件夹中只有一个文件 -> 然后在该单个文件中搜索
3- 文件夹中有多个文件 -> 然后找到最近的文件并在该文件内搜索。

现在我有这个命令:

if [ -e ~/test/log.$(date +%Y%m%d)_?? ]; then ls -tr1 ~/test/log.$(date +%Y%m%d)_?? | tail -1 | xargs grep -q "WARNING"; else exit 123; fi

此命令适用于第一种和第二种情况,但不适用于第三种情况。如果发生第 3 种情况,我会收到bash: [: too many arguments错误,然后它会落入 else 子句

知道为什么会发生这种情况吗?

答案1

我将ls在循环中使用版本排序来代替:

$ for i in $(ls -r1v ~/test/log.* 2>/dev/null); do \
  grep -q "WARNING" < "$i" && echo match; break; done

另一个使用 read 的示例:

$ read -r < <(ls -r1v ~/test/log.* 2>/dev/null) && \
  { grep -q "WARNING" < "$REPLY" && echo match; } || echo file not found.

在脚本中,我更喜欢在使用文件之前检查其是否存在。

#!/bin/bash

mapfile -t -n 1 < <(ls -r1v ~/test/log.* 2>/dev/null)

[[ -e $MAPFILE ]] || \
    { echo file not found.; exit 123; }

grep -q "WARNING" < "$MAPFILE" && echo match || echo no match

答案2

谢谢大家的帮助,

在您的帮助下我找到了答案。

这个命令对我有用:

if [ "$(ls -1 ~/test/log.$(date +%Y%m%d)_?? 2>/dev/null | wc -l)" -gt 0 ]; then ls -tr1 ~/test/log.$(date +%Y%m%d)_?? | tail -1 | xargs grep -q "WARNING"; else exit 123; fi

因此,我检查文件数量是否大于 0,然后找到最新的文件并在其中进行 grep。

2>/dev/null帮助我在文件夹中不存在文件的情况下绕过No such file or directory错误。您可以参考此评论https://stackoverflow.com/a/40714363/1908331为了那个原因

相关内容