Answers:
假设GNU设施:
find . -mtime -1 -exec bash -c \
'for f; do tac "$f" | grep -m1 fileprefix; done' _ {} +
find
来对文件执行命令-exec
。使用bash -c
,我们产生了一个bash
shell,该shell循环遍历由它们找到find
并tac .. | grep -m1 fileprefix
在每个文件上执行的文件
-d" "
与cut 一起使用。双引号代替单引号
find
命令可以过滤文件前缀。该grep
不需要的。同样令人惊讶的是,搜索字符串未包含在此答案中。
如果所有内容都在一个目录中,则可以执行以下操作:
for file in *fileprefix*; do
grep 'search string' "$file" | tail -1
done
如果这些文件很大,则可能有必要通过tac
以相反的顺序打印文件(最后一行在第一行)然后grep -m1
匹配第一个出现的文件来加快处理速度。这样,您就不必读取整个文件:
for file in *fileprefix*; do
tac file | grep -m1 'search string'
done
两者都假定没有匹配的目录fileprefix
。如果有,您将收到一个错误,可以忽略。如果这是一个问题,请仅检查文件:
for file in *fileprefix*; do
[ -f "$file" ] && tac file | grep -m1 'search string'
done
如果还需要打印文件名,请添加-H
到每个grep
调用中。或者,如果您grep
不支持它,请告诉它也搜索/dev/null
。这不会改变输出,但是由于grep
提供了多个文件,因此它将始终为每次匹配显示文件名:
for file in *fileprefix*; do
grep 'search string' "$file" /dev/null | tail -1
done
tac
其中。一旦找到第一个比赛,它将退出。我刚刚测试了832M文本文件和在最后一行找到的模式。grep -m 1 pattern file
工具约7秒钟,tac file | grep -m1 pattern
耗时0.009
。
find . ! -name . -prune -mtime 1 -name 'fileprefix*' \
-exec sed -se'/searchstring/h;$!d;x' {} +
如果您拥有sed
支持-s
eparate files选项和POSIX的GNU ,它将起作用find
。
不过,您可能应该添加! -type d
或-type f
限定符,因为尝试读取目录不会很有用,并且进一步将范围缩小到常规文件可以避免读取挂在管道或串行设备文件上。
逻辑非常简单- sed
用h
匹配的任何输入行的副本覆盖旧空间searchstring
,然后d
从输出中删除所有输入行,但删除每个输入文件的最后一行。当到达最后一行时,它将x
更改其保留空间和模式空间,因此,如果searchstring
在读取文件时完全找到它,则最后一次出现的情况将自动打印输出,否则将写入空白行。(如果不希望的话,请添加/./!d
到sed
脚本的末尾)。
这将对sed
大约65k个输入文件执行一次调用-或您的ARG_MAX
限制是多少。这应该是一个非常高效的解决方案,并且非常容易实现。
如果您还想要文件名,则在给定最新GNU的情况下,sed
您可以使用F
命令将它们写到单独的行中,否则,可以通过find
在后面附加-print
主文件来在每批的单独列表中打印它们+
。
怎么样:
find . -mtime -1 -name "fileprefix*" -exec sh -c \
'echo "$(grep 'search string' $1 | tail -n 1),$1"' _ {} \;
上面的代码为您提供了一个不错的输出,每个文件中最后出现一个搜索字符串,后跟逗号后的相应文件名(修改echo之下的“,$ 1”部分以更改格式,或者在不必要时将其删除)。在带有“文件”名称前缀的文件中搜索“ 10”搜索字符串的示例输出如下:
[dmitry@localhost sourceDir]$ find . -mtime -1 -name "file*" -exec sh -c 'echo "$(grep '10' $1 | tail -n 1),$1"' _ {} \;
Another data 02 10,./file02.log
Some data 01 10,./file01.log
Yet another data 03 10,./file03.log
find . -mtime 1 -name 'fileprefix*' -exec grep -Hn 'search string' {} + |
sort -t: -k1,2 -n |
awk -F: '{key=$1 ; $1="" ; $2="" ; gsub(/^ /,"",$0); a[key]=$0}
END {for (key in a) { print key ":" a[key] }}'
它使用GNU grep
的-H
和-n
选择总是同时打印文件名和所有匹配的行号,然后它按文件名和行号,和管道入AWK,这对于数组中的每个文件名的最后一场比赛专卖店,并最终打印它。
一种蛮力的方法,但是可以用。