Извлечение содержимого между двумя шаблонами из файла - PullRequest
0 голосов
/ 20 января 2020

Я хочу извлечь следующее содержимое между The SUMMARY и End processing summary for first university, а также The SUMMARY и End processing summary for second university

Это мой файл:

Logs here
...
...
...
More logs here
...
...

The SUMMARY
Total students: 1200
Total teachers: 10
Total subjects: 20
Total attendance: 12000
End processing summary for first university

Logs here
...
...
...
More logs here
...
...

The SUMMARY
Total students: 1500
Total teachers: 12
Total subjects: 15
Total attendance: 20000
End processing summary for second university

Logs here
...
...
...
More logs here
...
...

следующие работы прекрасно работают:

firstUniversity=$(awk '/The SUMMARY/ && ++n == 1, /End processing summary for first university/' < theLog.log)

secondUniversity=$(awk '/The SUMMARY/ && ++n == 2, /End processing summary for second university/' < theLog.log)

Однако , иногда либо the summary for first university, либо the summary for second university отсутствует, и приведенный выше код не работает.

Первый отсутствует университетский блок

Logs here
...
...
...
More logs here
...
...
Logs here
...
...
...
More logs here
...
...

The SUMMARY
Total students: 1500
Total teachers: 12
Total subjects: 15
Total attendance: 20000
End processing summary for second university

Logs here
...
...
...
More logs here
...
...

или отсутствует второй университетский блок

Logs here
...
...
...
More logs here
...
...

The SUMMARY
Total students: 1200
Total teachers: 10
Total subjects: 20
Total attendance: 12000
End processing summary for first university

Logs here
...
...
...
More logs here

Любое решение, использующее sed или awk команды?

Ответы [ 2 ]

1 голос
/ 20 января 2020

Немного другой подход к awk:

cat extract.awk

/The SUMMARY/ {                                       # match starting line
  s = $0                                              # set s to current line
  p = 1                                               # set flag p to 1
}
p {                                                   # if flag p is set
   s = s ORS $0                                       # keep adding lines to s
}
$0 ~ "End processing summary for " kw " university" { # when we find end line
   print s                                            # print full text
   p = 0                                              # reset p to 0
}

Затем используйте его как:

firstUniversity="$(awk -v kw='first' -f extract.awk inputFile)"
secondUniversity="$(awk -v kw='second' -f extract.awk inputFile)"

Без использования файла сценария awk:

firstUniversity="$(awk -v kw='first' '/The SUMMARY/{s=$0; p=1} p{s = s ORS $0}
$0 ~ "End processing summary for " kw " university"{print s; p=0}' inputFile)"

secondUniversity="$(awk -v kw='second' '/The SUMMARY/{s=$0; p=1} p{s = s ORS $0}
$0 ~ "End processing summary for " kw " university"{print s; p=0}' inputFile)"
1 голос
/ 20 января 2020

Не могли бы вы попробовать, написано и протестировано с показанными образцами. В этом решении для ясности я создал переменную found_university.

awk '
/The SUMMARY/{
   found_summary=1
   val=found_university=""
}
/End processing summary for first university|End processing summary for second university/{
   found_university=1
   if(found_university && found_summary){
     print val ORS $0
   }
   val=found_university=found_summary=""
}
found_summary{
   val=(val?val ORS:"")$0
}
'  Input_file

Можно попробовать следующее, которое не использует переменную found_university и просто проверяет условие появления университетской строки.

awk '
/The SUMMARY/{
   found_summary=1
   val=""
}
/End processing summary for first university|End processing summary for second university/{
   if(found_summary){
     print val ORS $0
   }
   val=found_summary=""
}
found_summary{
   val=(val?val ORS:"")$0
}
'   Input_file

Объяснение: Добавление подробного объяснения уровня для приведенного выше кода. Пожалуйста, прокрутите немного вправо, чтобы увидеть объяснение:)

awk '                                                                                             ##Starting awk program from here.
/The SUMMARY/{                                                                                    ##Checking condition if line has string The SUMMARY then do following.
   found_summary=1                                                                                ##Setting found_summary as 1 here.
   val=""                                                                                         ##Nullifying variable val here.
}
/End processing summary for first university|End processing summary for second university/{       ##Checking condition if university string present in line then do following.
   if(found_summary){                                                                             ##Checking condition if found_summary is SET then do following.
     print val ORS $0                                                                             ##Printing variable val ORS and current line here.
   }
   val=found_summary=""                                                                           ##Nullifying variables val and found_summary here.
}
found_summary{                                                                                    ##Checking condition if found_summary is SET then do following.
   val=(val?val ORS:"")$0                                                                         ##Keep concatenating current line in val value.
}
'  Input_file                                                                                       ##Mentioning Input_file name here.
...