Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux 在shell脚本中从文件中grep某些内容_Linux_Bash_Shell - Fatal编程技术网

Linux 在shell脚本中从文件中grep某些内容

Linux 在shell脚本中从文件中grep某些内容,linux,bash,shell,Linux,Bash,Shell,我有一份文件,内容如下: [1412272372] SERVICE ALERT: abc.com;value;WARNING;HARD;3;WARNING: 2014-09-14 [1412272412] SERVICE ALERT: def.com;value;WARNING;HARD;3;WARNING: 2014-09-14 [1412272432] SERVICE ALERT: fgh.com;value;WARNING;HARD;3;WARNING: 2014-09-14 [14122

我有一份文件,内容如下:

[1412272372] SERVICE ALERT: abc.com;value;WARNING;HARD;3;WARNING: 2014-09-14
[1412272412] SERVICE ALERT: def.com;value;WARNING;HARD;3;WARNING: 2014-09-14
[1412272432] SERVICE ALERT: fgh.com;value;WARNING;HARD;3;WARNING: 2014-09-14
[1412272442] SERVICE ALERT: fgh.com;value;WARNING;HARD;3;CRITICAL: 2014-09-14
由此,我只想grep站点名称和日期,然后将其保存到一个新文件中。因此,在此之后,新文件应如下所示-

abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
任何帮助都将不胜感激

提前谢谢

$ awk -F'[:;]' '{print $2 " -" $NF}' data
 abc.com - 2014-09-14
 def.com - 2014-09-14
 fgh.com - 2014-09-14
 fgh.com - 2014-09-14
说明:

  • -F'[:;]'

    数据的特殊部分是字段有时用冒号分隔,有时用分号分隔。使用
    -F
    选项,我们告诉
    awk
    接受任一字符作为字段分隔符

  • 打印$2“-”$NF

    这将打印输出<代码>$2指第二个字段,即站点名称。日期是最后一个字段,由
    $NF
    表示

只保留唯一的结果 说明:

  • -F'[:;]'

    数据的特殊部分是字段有时用冒号分隔,有时用分号分隔。使用
    -F
    选项,我们告诉
    awk
    接受任一字符作为字段分隔符

  • 打印$2“-”$NF

    这将打印输出<代码>$2指第二个字段,即站点名称。日期是最后一个字段,由
    $NF
    表示

只保留唯一的结果
您可以尝试下面的awk命令

$ awk -F'[:; ]' '{print $5" - "$12}' file
abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
fgh.com - 2014-09-14

您可以尝试下面的awk命令

$ awk -F'[:; ]' '{print $5" - "$12}' file
abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
fgh.com - 2014-09-14
只有在该日期之前未看到该站点时,才会打印该站点。因此,它产生:

 abc.com - 2014-09-14
 def.com - 2014-09-14
 fgh.com - 2014-09-14
abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
输出在站点名称的开头包含一个空格。如果您也希望消除这种情况,那么您需要:

awk -F'[:; ]' '{if (seen[$5,$NF]++ == 0) print $5 " - " $NF}' data
每次出现冒号和空格之间都有一个空字段。这将产生:

 abc.com - 2014-09-14
 def.com - 2014-09-14
 fgh.com - 2014-09-14
abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
(无可否认,这与之前的产出非常相似)

您可以使用可重复的分隔符来消除空字段:

awk -F'[:; ]+' '{if (seen[$4,$NF]++ == 0) print $4 " - " $NF}' data
这与上一个脚本的输出相同

只有在该日期之前未看到该站点时,才会打印该站点。因此,它产生:

 abc.com - 2014-09-14
 def.com - 2014-09-14
 fgh.com - 2014-09-14
abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
输出在站点名称的开头包含一个空格。如果您也希望消除这种情况,那么您需要:

awk -F'[:; ]' '{if (seen[$5,$NF]++ == 0) print $5 " - " $NF}' data
每次出现冒号和空格之间都有一个空字段。这将产生:

 abc.com - 2014-09-14
 def.com - 2014-09-14
 fgh.com - 2014-09-14
abc.com - 2014-09-14
def.com - 2014-09-14
fgh.com - 2014-09-14
(无可否认,这与之前的产出非常相似)

您可以使用可重复的分隔符来消除空字段:

awk -F'[:; ]+' '{if (seen[$4,$NF]++ == 0) print $4 " - " $NF}' data
这与上一个脚本的输出相同。

不带awk:

$ grep WARNING file.log |
    cut --delimiter=":" --output-delimiter=";" --fields=2,3 |
    cut --delimiter=";" --output-delimiter=" -" --fields=1,7
它比awk更冗长,但也更具可读性。如果需要唯一的条目,请通过管道将结果排序到
sort-u

如果不进行筛选,只需删除grep命令并在第一次剪切时添加文件名:

$ cut -d : --output-delimiter=";" --fields=2,3 file.log |
    cut --delimiter=";" --output-delimiter=" -" --fields=1,7 |
    sort --unique
没有awk:

$ grep WARNING file.log |
    cut --delimiter=":" --output-delimiter=";" --fields=2,3 |
    cut --delimiter=";" --output-delimiter=" -" --fields=1,7
它比awk更冗长,但也更具可读性。如果需要唯一的条目,请通过管道将结果排序到
sort-u

如果不进行筛选,只需删除grep命令并在第一次剪切时添加文件名:

$ cut -d : --output-delimiter=";" --fields=2,3 file.log |
    cut --delimiter=";" --output-delimiter=" -" --fields=1,7 |
    sort --unique

只是为了增加。。。您也可以使用AWK中的数组解决此问题:

awk-F'[:;]'{arr[$2,“-”,$8]+}END{for(arr中的a)打印a}'


这将通过分号或冒号进行拆分,然后将元素2和8发送到数组,然后使用for循环遍历数组,打印找到的每个元素,从而只显示唯一的值。

只需将其添加到堆栈中即可。。。您也可以使用AWK中的数组解决此问题:

sed -E 's/.*: ([^;]*);.*: (.*)/\1 - \2/' file | uniq
awk-F'[:;]'{arr[$2,“-”,$8]+}END{for(arr中的a)打印a}'

这将以分号或冒号分隔,然后将元素2和8发送到数组,然后使用for循环遍历数组,打印它找到的每个元素,从而只通过唯一的值

sed -E 's/.*: ([^;]*);.*: (.*)/\1 - \2/' file | uniq
输出:

abc.com - 2014-09-14 def.com - 2014-09-14 fgh.com - 2014-09-14 abc.com-2014-09-14 def.com-2014-09-14 fgh.com-2014-09-14 或具有相同输出的异常情况:

tr -s ":; " ":" < file | cut -d : -f 4,10 --output-delimiter=" - " | uniq
tr-s:;“”:“
输出:

abc.com - 2014-09-14 def.com - 2014-09-14 fgh.com - 2014-09-14 abc.com-2014-09-14 def.com-2014-09-14 fgh.com-2014-09-14 或具有相同输出的异常情况:

tr -s ":; " ":" < file | cut -d : -f 4,10 --output-delimiter=" - " | uniq
tr-s:;“”:“
Grep帮不上忙…试试awk或sed,你想要一个独特的站点+日期条目列表吗?输出中有一个2014-09-14的
fgh.com
条目,尽管输入中有两行。@Abhi:
grep
单独可能不够,但是
grep
+
cut
+
排序功能非常强大。unix的美妙之处在于,许多小程序都能很好地完成一件事,可以组合起来完成复杂的任务!Grep帮不上忙…试试awk或sedSo你想要一个独特的站点+日期条目列表吗?输出中有一个2014-09-14的
fgh.com
条目,尽管输入中有两行。@Abhi:
grep
单独可能不够,但是
grep
+
cut
+
排序功能非常强大。unix的美妙之处在于,许多小程序都能很好地完成一件事,可以组合起来完成复杂的任务!线条末端的反斜杠是不必要的。我猜情人眼里出西施;我不喜欢看到在一个命令足够的地方使用三个命令。此外,不清楚您是否可以忽略“关键”行;可能有一个网站在某一天只显示关键警报。问题的样本输出比输入短一行,因此我推断他想过滤掉关键警报(当然“关键”似乎比“警告”更重要,但嘿,这不是我的问题:-)。好的,反斜杠消失了,但是你可以说一些引号也是可选的。我是一名Python程序员,“显式优于隐式”。行末尾的反斜杠是不必要的。我猜情人眼里出西施;我不喜欢看到在一个命令足够的地方使用三个命令。还有,现在还不清楚哟