我想使用另一个文件的输入来 grep 日志文件中的某些行。我正在使用这个小命令来做到这一点:
while read line; do
grep "$line" service.log;
done < input_strings.txt > result.txt
input_strings.txt
有大约 50 000 个字符串(每行一个)。对于这个字符串中的每一个,我当前正在搜索巨大的service.log
文件(大约有 2 000 000 行)。
假设第一个字符串是在第 10 000 行input_strings.txt
找到的,这一行被写入到我的.之后,将在 中搜索 的第二个字符串,但从 的第 1 行开始。service.log
result.txt
input_strings.txt
service.log
service.log
我如何记住在 中找到第一个条目的最后一行service.log
?这样我就可以在那里开始第二次搜索运行?
答案1
如果你想获得匹配,那么你根本不需要使用循环。仅使用单个命令会快得多grep
:
grep -Ff input_strings service.log > results.txt
也就是说,如果您想按字面意思执行问题中所述的操作,那么您可以使用变量来跟踪找到最后一个匹配项的行:
LINE_NUMBER=0
while read LINE; do
# Search for the next match starting at the line number of the previous match
MATCH="$(tail -n+${LINE_NUMBER} "service.log" | grep -n "${LINE}" | head -n1)";
# Extract the line number from the match result
LINE_NUMBER="${MATCH/:*/}";
# Extract the matching string from the match result
STRING="${x#*:}";
# Output the matching string
echo "${STRING}";
done < input_strings.txt > result.txt
答案2
我猜你想搜索第一个关键字,然后在该匹配之后继续搜索下一个关键字等,并打印匹配的内容。
鉴于keywords
:
foo
bar
和data
:
bar 0
foo 1
bar 1
foo 2
这里的脚本awk
应该做到这一点(使用 GNU awk 测试):
$ awk 'BEGIN {i = j = 0} NR==FNR { k[i++] = $0; next}
$0 ~ k[j] {j++; print $0} j >= i {exit}' keywords data
foo 1
bar 1
i
从 0开始j
,在第一个文件期间(将NR==FNR
当前文件的记录/行号与所看到的总行数进行比较),我们将关键字收集到一个数组中。之后,尝试匹配j
:th 关键字,并j
在匹配时打印并增加。找到所有关键字后退出。
与 一样grep
,这里的关键字实际上是正则表达式模式,尽管awk
这里显然是正则表达式。如果您想搜索固定字符串,请使用index($0, key)
代替$0 ~ key
。
或者,在开始时不加载关键字:
$ awk -vkeyfile=keywords 'BEGIN {getline key < keyfile }
$0 ~ key {print $0; if (!getline key < keyfile) exit;}' data
foo 1
bar 1
这应该很简单。