Bash grep多个文件中的多个字符串,并在找到第一个匹配项时停止处理其他文件

Bash grep多个文件中的多个字符串,并在找到第一个匹配项时停止处理其他文件,bash,grep,Bash,Grep,我有ca 270.bz2日志文件(25天日志)和一个包含ca 1500用户名的文本文件。我需要做的是找出在过去25天中有哪些用户登录。所以我需要从文件列表中grep用户名,并在第一个文件中找到用户名时停止grep(当找到第一个匹配项时) 我的代码有效,但如果在第一个文件中找到匹配项,我不需要处理其他文件,请中断并搜索其他用户名,如果在第三个文件中找到,请中断并搜索其他用户名: for i in $(cat /tmp/usernames.txt); do for j in $(ls *.bz2);

我有ca 270.bz2日志文件(25天日志)和一个包含ca 1500用户名的文本文件。我需要做的是找出在过去25天中有哪些用户登录。所以我需要从文件列表中grep用户名,并在第一个文件中找到用户名时停止grep(当找到第一个匹配项时)

我的代码有效,但如果在第一个文件中找到匹配项,我不需要处理其他文件,请中断并搜索其他用户名,如果在第三个文件中找到,请中断并搜索其他用户名:

for i in $(cat /tmp/usernames.txt); do for j in $(ls *.bz2); do 
bzgrep -o -m1 $i $j; done; done
在这里,如果在第一个文件中match发现它会中断(-m1标志),并开始在第二个文件中搜索相同的用户名,但我不再需要它了

问题:我需要检查过去25天内未登录的用户。所以我可以减少他们在应用程序中的权限。若用户在过去25天内至少登录一次,我不会减少他的权限

问题是:我需要找到这些用户名中的谁存在于我的日志文件中。如果至少有一次在其中一个文件中找到用户名,请停止搜索此用户并开始搜索其他用户


示例:如果在文件1中找到user1,请打印它并停止在此文件或其他文件中搜索此用户。如果在文件8中找到user2,请将其打印一次并停止在文件9、文件10、文件11中搜索。。。文件250。希望它有意义。

您可以使用条件:

if [ -n "$var" ]; then
     echo "Match!"
     break
fi
此结构意味着只有当$var不为空时,条件才为真。当条件变为真时,循环将停止。
祝你好运

如果磁盘空间不是一个问题,我会要求bzip2将所有存档解压缩到一个文件中,并为每个用户名调用该文件上的
grep-m1

bzcat *.bz2 > merged
while IFS='' read -r username; do
  grep -om1 "$username" merged
done < /tmp/usernames.txt
rm merged
bzcat*.bz2>合并
而IFS=''read-r用户名;做
grep-om1“$username”合并
完成
您不能这样做以获取出现在任何BZIP文件中的用户名列表:

bzgrep -o -w -F -f /tmp/usernames.txt *.bz2 | sort -u
然后将该输出与usernames.txt进行比较,以查看谁已登录/未登录?如果一次检查一个.bz2文件更有效,则将其包装在循环中:

for file in *.bz2; do
    bzgrep -o -w -F -f /tmp/usernames.txt "$file"
done | sort -u
如果这样也能提高性能,您可以从每次迭代中删除找到的用户名:

sort -u /tmp/usernames.txt > /tmp/names.txt
for file in *.bz2; do
    bzgrep -o -w -F -f /tmp/names.txt "$file" | sort -u > /tmp/found.txt &&
    comm -23 /tmp/names.txt /tmp/found.txt > /tmp/left.txt &&
    mv /tmp/left.txt /tmp/names.txt &&
    cat /tmp/found.txt
    [[ -s /tmp/names.txt ]] || break
done

请说明你需要什么。问题是什么?您不需要嵌套循环。您可以
bzgrep
将名称与如下文件列表相匹配:
for i in$(cat/tmp/usernames.txt);bzgrep-o-m1$i$(ls*.bz2);完成
或匹配文件上的名称列表,以$(ls*.bz2)表示i;dobzgrep-o-m1-f/tmp/usernames.txt$i;完成侧注:<代码>用于*.bz2中的j;do…更健壮。@DudiBoy这里不需要
$(ls*.bz2)
,只要
*。bz2
将同样工作,并正确处理文件名中的空格等。无论如何,这是错误的答案,因为它将从每个文件返回第一个匹配项,这是OP的具体问题。使用现有代码,您可以检查grep返回的状态。假设它与unix grep兼容:
EXIT STATUS:通常,如果选择了一行,则退出状态为0;如果未选择任何行,则退出状态为1;如果发生错误,则退出状态为2。但是,如果使用-q或--quiet或--silent并且选择了一行,则即使出现错误,退出状态也为0。
因此添加
if$;然后打破;fi
可能有帮助吗?发生了`