从结构化文件中读取以调用匹配的 grep

从结构化文件中读取以调用匹配的 grep

已获得一个日志文件,其中包含文件名的结构化列表,第一个文件由描述符标识File:,其余文件位于单独的行上,+开头有一个字符。

我想要一个循环,一旦File:检测到,就使用匹配的模式打印文件名。然后它将继续拾取+开头的文件名。当到达空行或遇到另一个字段名称时,文件读取停止(例如Package:

cat /home/flora/logs/27043-T13:09:44.893003954.log
%rec: dyna

Ptrn: Gnu
File: /home/flora/dynamic.sh
+ /home/flora/comint.sh
+ /home/flora/linge/engine.sh
+ /home/flora/Opstk/playa.sh
+ /home/flora/bin/edv.sh
+ /home/flora/Opstk/bin/ling.rc
+ /home/flora/parade.rc
System: 64-Bit

从一个简单的开始read,以免使用变量来存储整个文件列表时导致内存不足问题。

while IFS= read -rd '' fl; do
  grep --color -ni -C 8 -e "$ptrn" -- "$fl"
done < "$logfl"

ptrn定义对每个文件调用的搜索模式。

答案1

在对该问题的评论中recutils,您提到您已将这些数据转换为 GNU工具集可读的格式。

让我们使用这些工具来提取路径名并调用grep

recsel -P File -- "$logfl" | xargs -I {} grep -e "$ptrn" -- {}

File这将选择并打印与名为 的文件中的字段关联的值$logfl。对于命令生成的每一行recselxargs调用grep以提取与 中的基本正则表达式匹配的行$ptrn

请注意,问题文件中的内容是单身的值,包含嵌入的换行符。

如果您有一个记录文件,其中包含多个File带有单独值的字段,您可以使用

recsel -C -P File -- "$logfl" | xargs -I {} grep -e "$ptrn" -- {}

答案2

使用进程替换并仅传递带有文件名的行进行循环(而不是整个文件)

while IFS= read -r fl; do
  grep --color -ni -C 8 -e "$ptrn" -- "$fl"
done < <(grep -o '/.*' "$logfl")

或处理整个文件,但逐行跳过直到关键字File:出现,然后通过字符串操作逐行处理/${fl#*/}直到关键字+消失,然后停止读取

# some control flags
begin=
exit=continue

while IFS= read -r fl; do
  case ${fl%[[:blank:]]*} in
    *File:*)
      begin=start
    ;;
    *+*)
      exit=break
    ;;
    *)
      $exit
    ;;
  esac
  [ "$begin" ] && \
  grep --color -ni -C 8 -e "$ptrn" -- "/${fl#*/}"
done < "$logfl"

相关内容