在文件中每行搜索一个单词,然后搜索特定消息下的几行

时间:2011-02-04 00:55:02

标签: bash

根据前体要求迭代文件并获取特定字符串的问题。

我是bash脚本的新手,已经在线阅读了初学者和高级教程,但是找不到能解决这个问题的任何内容。

我有一个日志文件,我正在尝试搜索特定的单词(以下示例中的XXXX)

如果/当脚本找到该单词时,则搜索下几行并输出位于值“/ * * /”

之间的消息

因此,脚本需要能够遍历整个日志文件,并且只能在“/ * * /”之间获取消息,但只能在看到XXXX之后。

这是一个需要迭代的示例文件。 该脚本应该提取2条错误消息。


TRD sdfnWW4
<
   computer_name  11-02-03 17:03:30
T  sdfnWW4 XXXXX
   MFKG
   "::fmksdfjes"
   /* Error message #1 to grab */
asfdadsf
adfadfasd
fasd
sd
-
RAS WEASDF
<
   computer_name  11-02-03 18:03:30
   WEASDF
   "::fmksdfjes"
sdfa
thmghjg
g5w45g5

<
 sdfnWW4
<
   computer_name  11-02-03 17:03:30
T  sdfnWW4 XXXXX
   MFKG
   "::fmksdfjes"
   /* Error message #2 to grab */
adfadfasd
sd

这是我开始使用的脚本,简单的文件读取脚本,但XXXX搜索后的代码是我难倒的地方。

#!/bin/sh

echo enter file name
read fname

exec<$fname
value=0
while read line
 do
  if [[ $line == *XXXX* ]]
  then
   "this is the part that has me stumped"
  fi
 done

提前感谢您的帮助。

3 个答案:

答案 0 :(得分:1)

如果你有Ruby(1.9 +)

$ ruby -ne 'BEGIN{$/="<"};puts $_.scan(/\/\*(.*?)\*\//)[0][0] if /XXXXX/' file
 Error message #1 to grab
 Error message #2 to grab

如果没有,awk

$ awk 'BEGIN{RS="<";FS="*/"} /XXXXX/{ gsub(/.*\/\*/,"",$1) ;print $1 }' file
 Error message #1 to grab
 Error message #2 to grab

答案 1 :(得分:0)

如果您可以访问grep,grep可以轻松过滤相关行。我建议你阅读这个命令,但是你做了

grep XXXX filename -A3

将从名为filename的文件中输出行,其中包含字符串XXXX和每个实例后的3行,这是您想要的。然后你可以通过将输出汇总到另一个grep来过滤掉非注释行来从那里提取注释文本:

grep "/*"

合并,这是:

grep XXXX filename -A3 | grep "/*"

答案 2 :(得分:0)

您可以在找到标记时设置标记,然后如果设置了标记,则递增计数器。如果计数器未超过阈值并找到您要查找的行,请将其打印出来。否则重置标志和计数器。你可以简单地使用计数器作为标志。

#!/bin/bash
# UNTESTED - check especially for off-by-one errors

limit=4

read -r -p "enter file name: " fname

exec<$fname
value=0
while read line
do
    if [[ $line == *XXXX* ]]
    then
        counter=1
    fi
    if (( counter > 0 && counter <= limit ))
    then
        if [[ $line == */\**/\** ]]
        then
            printf '%s\n' "$line"
            # setting counter to zero here means only the first instance is printed
            # remove it to print multiple instances following a marker
            counter=0
        fi
        (( counter = (counter + 1) % limit ))
    fi
done

请注意,我已将您的shebang更改为Bash,因为这是您标记问题的方式。