файл:
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
в различных местах.
Используя grep:
grep -Po '\bstring2.*string5\b' file.txt
Можно использовать 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")
и действие соответственно.
Эффективно, то, что Вы хотите сделать, выполняют итерации по каждому полю и "позволяют" печатать с переменной, если результат найден. Таким образом то, в чем Вы нуждаетесь, является переменной флага и для цикла:
$ 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