Поиск между шаблонами и процесс между шаблонами

#awk #sed

Вопрос:

У меня есть формат файла, как показано ниже,

 ####################### FILE Content ###################

Path 1
AND cell
OR1 cell
BUFF1 cell
OR2 cell
Ends

Path 2
OR1 cell
BUFF1 cell
AND1 cell
AND2 cell
BUFF2 cell
OR2 cell
Ends

Path 3
AND1 cell
AND2 cell
AND3 cell
OR1 cell
Ends

##########################################
 

Мне нужен вывод, как показано ниже:

 Path 1 - BUFF* count 1

Path 2 - BUFF* count 2

Path 3 - No BUFF
 

Используя sed, я могу сначала создать шаблон, подобный шаблону.
sed -n '/Path/,/Ends/p'
Далее, чтобы получить выход после этого, мне нужна ваша экспертная помощь.
кто-нибудь может мне помочь, пожалуйста.

Спасибо, ГБ

Ответ №1:

Вы можете использовать awk и использовать шаблоны, чтобы проверить, находитесь ли вы между путем, за которым следует цифра, и концами.

Когда он совпадет Ends , выведите текущий путь, по которому вы находитесь, и количество БАФФОВ.

Затем сбросьте видимые переменные и бафф.

 awk '
/^Path [0-9] /{seen=1; buff=0; path=$0; next}
{
  if(seen amp;amp; $1 ~ /^BUFF[0-9] $/){  buff;}
}
{
  if(seen amp;amp; $1 ~ /^Ends$/){
    print path " - " (buff ? "BUFF* count " buff : "No BUFF")
    seen=0; buff=0    
  }
}
' file
 

Выход

 Path 1 - BUFF* count 1
Path 2 - BUFF* count 2
Path 3 - No BUFF
 

Ответ №2:

С вашими показанными образцами, попытайтесь; пожалуйста, попробуйте выполнить следующий код awk .

 awk '
/Path/{
  if(count){
     print pathVal," - BUFF* count "(count?count:"NO BUFF")
  }
  found=""
  count=0
  pathVal=$0
  next
}
/BUFF/{
  count  
}
/Ends/{
  found=1
}
END{
  if(found){
     print pathVal," - BUFF* count "(count?count:"NO BUFF")
  }
}
'  Input_file
 

Пояснение: Добавление подробного объяснения вышеизложенного.

 awk '             ##Starting awk program from here.
/Path/{           ##If line contains Path then do following.
  if(count){      ##If count is set then do following.
     print pathVal," - BUFF* count "(count?count:"NO BUFF") ##Printing output with variables and string as per OP need here.
  }
  found=""        ##Nullifying found here.
  count=0         ##Setting 0 to count here.
  pathVal=$0      ##Setting current line to pathVal here.
  next            ##next will skip all further statements from here.
}
/BUFF/{           ##Checking if BUFF is found in line then increase count with 1 here.
  count  
}
/Ends/{           ##Checking if Line contains Ens then setting found to 1 here.
  found=1
}
END{              ##Starting END block of this program from here.
  if(found){      ##If found is set then print as per OP requirement values with strings.
     print pathVal," - BUFF* count "(count?count:"NO BUFF")
  }
}
'  Input_file     ##Mentioning Input_file name here. 
 

Комментарии:

1. Но, конечно, это здорово. Я потратил некоторое время на то, чтобы собрать его вместе, поэтому я подумал, что давайте опубликуем это. Я забыл о next звонке, поэтому добавил его.

Ответ №3:

Это может сработать для вас (GNU sed и оболочка):

 sed -n '/^Path.*/{s//amp; - BUFF* count $((0))/;h}
        /^BUFF/{g;s/(0/(0 1/;h}
        /^Ends/{g;/ /!s/-.*/- No BUFF/;s/^Path.*/echo "amp;"/ep;z;h}' file
 

Для каждого Path сделайте копию, добавьте немного текста и инициализируйте счетчик.

Для каждого BUFF приращения используется счетчик.

Для каждого Ends из них замените добавленный текст другим текстом , если счетчик не был увеличен. Заключите все сообщение в двойные кавычки и повторите результат путем оценки результата, а затем очистите его.

N. B. Счетчик будет интерполирован в двойных кавычках команды echo.

Ответ №4:

С awk в режиме абзаца и использованием gsub() функции для определения того, сколько раз /BUFF[[:digit:]] / появляется:

 awk -v RS= -v FS='n' '
   $1 ~ /Path/ amp;amp; $NF == "Ends"  amp;amp; /BUFF/{
           n=gsub(/BUFF[[:digit:]] /,"amp;");print $1 " - BUFF* count " n}
   $1 ~ /Path/ amp;amp; $NF == "Ends"  amp;amp; !/BUFF/{
           print $1 " - No BUFF"}
' file
Path 1 - BUFF* count 1
Path 2 - BUFF* count 2
Path 3 - No BUFF