Печать AWK от шаблона до шаблона

файл:

string1 string2 string3 string4 string5 string6  
string3 string1 string2 string4 string5 string6  
string6 string3 string2 string4 string1 string5

ожидание:

string2 string3 string4 string5  
string2 string4 string5  
string2 string4 string1 string5

Шаблон соответствия =string1
Как распечатать строки соответствия, но только от string2 кому: string5 с awk ?

К сожалению, это не обрабатывает в строке:

 awk '/string2/,/string5/' file 

Давайте предположим, что существует немного длинных линий с string2 и string5 в различных местах.

0
задан 5 March 2017 в 11:55

3 ответа

Используя grep:

grep -Po '\bstring2.*string5\b' file.txt
1
ответ дан 3 November 2019 в 16:26

Можно использовать awk's index и match функции, например.

awk 'match($0,/string5/) {
  START2 = index($0,"string2");
  print substr($0,START2,RSTART+RLENGTH-START2)
}' file

Напр.

$ mawk 'match($0,/string5/) {
  START2 = index($0,"string2");
  print substr($0,START2,RSTART+RLENGTH-START2)
}' file
string2 string3 string4 string5
string2 string4 string5
string2 string4 string1 string5

Обратите внимание, что это принимает это string2 будет существовать в каждой строке в который string5 существует - если это не так, необходимо будет проверить значение index($0,"string2") и действие соответственно.

3
ответ дан 3 November 2019 в 16:26

Эффективно, то, что Вы хотите сделать, выполняют итерации по каждому полю и "позволяют" печатать с переменной, если результат найден. Таким образом то, в чем Вы нуждаетесь, является переменной флага и для цикла:

$ cat file.txt
string1 string2 string3 string4 string5 string6
string3 string1 string2 string4 string5 string6
string6 string3 string2 string4 string1 string5

$ awk '{flag=0;for(i=1;i<=NF;i++){ if($i=="string2") flag=1; if($i=="string6") flag=0;  if(flag)printf "%s%s",$i,FS;};print"";}' file.txt  
string2 string3 string4 string5 
string2 string4 string5 
string2 string4 string1 string5 

Что происходит, вот то, что целый блок кода будет работать за каждой строкой. На каждой строке мы выполняем итерации от первого поля для длительности. Первоначально мы устанавливаем переменную флага на 0, затем продолжаем исследовать каждое поле. Если поле будет содержать желаемый "string2", то флаг будет установлен на 1, и если это будет "string6" (который является тем, когда мы захотим остановиться) - то флаг будет установлен на 0; наконец, если оператор проверит, установлен ли флаг, и распечатайте текущее поле, добавленное с разделителем полей (представленный переменной FS). В конце концов, был распечатан, мы также вставляем новую строку через print "" команда.

В случае, если, где у Вас есть уникальные строки, вышеупомянутая команда распечатает пустые строки. Можно смягчить это через добавляющий шаблон поиска, который ограничит выполнение блока кода только, когда будет шаблон, найденный в строке:

$ cat file.txt
string1 string2 string3 string4 string5 string6
blah blah
string3 string1 string2 string4 string5 string6
string6 string3 string2 string4 string1 string5

$ awk '$0~"string2"{flag=0;for(i=1;i<=NF;i++){ if($i=="string2") flag=1;  if(flag)printf "%s%s",$i,FS;};print"";}' file.txt
string2 string3 string4 string5 string6 
string2 string4 string5 string6 
string2 string4 string1 string5 

С другой стороны, мы можем использовать дополнительную переменную с тем же результатом:

$ awk '{j=0;f=0;for(i=1;i<=NF;i++){if($i=="string2"){j=1;f=1};if(f)printf "%s%s",$i,FS;};if(j)print"";}' file.txt        
string2 string3 string4 string5 string6 
string2 string4 string5 string6 
string2 string4 string1 string5
3
ответ дан 3 November 2019 в 16:26

Другие вопросы по тегам:

Похожие вопросы: