bash shell 脚本显示 grep 结果

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23459779/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:22:59  来源:igfitidea点击:

shell script display grep results

bashshellgrep

提问by user3486059

I need some help with displaying how many times two strings are found on the same line! Lets say I want to search the file 'test.txt', this file contains names and IP's, I want to enter a name as a parameter when running the script, the script will search the file for that name, and check if there's an IP-address there also. I have tried using the 'grep' command, but I don't know how I can display the results in a good way, I want it like this:

我需要一些帮助来显示在同一行上找到两个字符串的次数!假设我想搜索文件“test.txt”,该文件包含名称和 IP,我想在运行脚本时输入一个名称作为参数,脚本将搜索该名称的文件,并检查是否有IP地址也有。我曾尝试使用“grep”命令,但我不知道如何以一种好的方式显示结果,我希望它是这样的:

Name: John Doe IP: xxx.xxx.xx.x count: 3 

The count is how many times this line was found, this is how my grep script looks like right now:

计数是找到这一行的次数,这就是我的 grep 脚本现在的样子:

#!/bin/bash 
echo "Searching  for the Name ''"

result=$(grep ""  | grep -E "(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)")

echo $result 

I will run the script like 'sh search test.txt John'. I'm having trouble displaying the information I get from the grep command, maybe there's a better way to do this?

我将运行像“sh search test.txt John”这样的脚本。我无法显示从 grep 命令获得的信息,也许有更好的方法来做到这一点?

EDIT:

编辑:

Okey, I will try to explain a little better, let's say I want to search a .log file, I want a script to search that file for a string the user enters as a parameter. i.e if the user enters 'sh search test.log logged in' the script will search for the string "logged in" within the file 'test.log'. If the script finds this line on the same line as a IP-address the IP address is printed, along with how many times this line was found.

好吧,我会试着解释得更好一点,假设我想搜索一个 .log 文件,我想要一个脚本来搜索该文件以查找用户作为参数输入的字符串。即,如果用户输入“sh search test.log login”,脚本将在文件“test.log”中搜索字符串“logged in”。如果脚本在与 IP 地址相同的行中找到此行,则会打印 IP 地址以及找到此行的次数。

And I simply don't know how to do it, I'm new to shell scripting, and was hoping I could use grep along with regular expressions for this! I will keep on trying, and update this question with an answer if I figure it out.

而且我根本不知道该怎么做,我是 shell 脚本的新手,希望我可以将 grep 与正则表达式一起使用!我会继续尝试,如果我弄明白了,我会用答案更新这个问题。

I don't have said file on my computer, but it looks something like this:

我的电脑上没有该文件,但它看起来像这样:

Apr 25 11:33:21 Admin CRON[2792]: pam_unix(cron:session): session opened for user 192.168.1.2 by (uid=0)
Apr 25 12:39:01 Admin CRON[2792]: pam_unix(cron:session): session closed for user 192.168.1.2
Apr 27 07:42:07 John CRON[2792]: pam_unix(cron:session): session opened for user 192.168.2.22 by (uid=0)
Apr 27 14:23:11 John CRON[2792]: pam_unix(cron:session): session closed for user 192.168.2.22
Apr 29 10:20:18 Admin CRON[2792]: pam_unix(cron:session): session opened for user 192.168.1.2 by (uid=0)
Apr 29 12:15:04 Admin CRON[2792]: pam_unix(cron:session): session closed for user 192.168.1.2

回答by tripleee

Here is a simple Awk script which does what you request, based on the log snippet you posted.

这是一个简单的 awk 脚本,它根据您发布的日志片段执行您的请求。

awk -v user="" ' == user { i[]++ }
    END { for (a in i) printf ("Name: %s IP: %s count: %i\n", user, a, i[a]) }' ""

If the fourth whitespace-separated field in the log file matches the requested user name (which was passed to the shell script as its second parameter), add one to the count for the IP address (from field 11).

如果日志文件中以空格分隔的第四个字段与请求的用户名(作为第二个参数传递给 shell 脚本)匹配,则在 IP 地址的计数上加 1(来自字段 11)。

At the end, loop through all non-zero IP addresses, and print a summary for each. (The user name is obviously whatever was passed in, but matches your expected output.)

最后,循环遍历所有非零 IP 地址,并为每个地址打印摘要。(用户名显然是传入的任何内容,但与您的预期输出匹配。)

This is a very basic Awk script; if you think you want to learn more, I urge you to consult a simple introduction, rather than follow up here.

这是一个非常基本的 awk 脚本;如果你认为你想了解更多,我敦促你查阅一个简单的介绍,而不是在这里跟进。

If you want a simpler grep-only solution, something like this provides the information in a different format:

如果你想要一个更简单的grep解决方案,像这样的东西以不同的格式提供信息:

grep "" "" |
grep -o -E '(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)' |
sort | uniq -c | sort -rn

The trick here is the -ooption to the second grep, which extracts just the IP address from the matching line. It is however less precise than the Awk script; for example, a user named "sess" would match every input line in the log. You can improve on that slightly by using grep -win the first grep-- that still won't help against users named "pam" --, but Awk really gives you a lot more control.

这里的技巧是-o第二个选项grep,它只从匹配行中提取 IP 地址。然而,它不如 Awk 脚本精确;例如,名为“sess”的用户将匹配日志中的每个输入行。您可以通过grep -w在第一个中使用来稍微改进grep——这对于名为“pam”的用户仍然无济于事——但是 Awk 确实给了您更多的控制权。

My original answer is below this line, partly becaus it's tangentially useful, partially because it is required in order to understand the pesky comment thread below.

我的原始答案在这一行下方,部分是因为它在切线上很有用,部分是因为它是理解下面讨厌的评论线程所必需的。



The following

下列

result=$(command)
echo $result

is wrong. You need the second line to be

是错的。你需要第二行

echo "$result"

but in addition, the detour over echois superfluous; the simple way to write that is simply

但除此之外,绕道而行echo是多余的;简单的写法很简单

command