如果我的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为了那个原因