awk find lines between two strings, one of which is variable

Viewed 181

I am trying to find the text between the two lines, the starting line contains an index(variable), so I need to pass it from shell to awk. But I am not able to figure out how to mix /start/,/end/ construct with variables.

This is the input data:

echo "$x"
abc def 1
hey there
end

abc def 2
hello there
whats up
end

abc def 3
howdy
end

This works fine, but it is hard coding the index(Eg 2)

echo "$x" |awk '/abc def 2/,/end/'
abc def 2
hello there
whats up
end

Some naive attempts:

 -->echo "$x" |awk -vnum=2 '/abc def /2,/end/'
abc def 1
hey there
end

abc def 2
hello there
whats up
end

abc def 3
howdy
end

 -->echo "$x" |awk -vnum=2 'BEGIN{start="abc def "num}start,/end/'
abc def 1
hey there
end

abc def 2
hello there
whats up
end

abc def 3
howdy
3 Answers

With your shown attempts, please try following awk code. This is one way of passing awk variable value to search range. Using match function of awk and matching string with variable till string end(taken from OP's attempts here) to Print matched lines.

echo "$x" | awk -v val="2" 'match($0,"abc def " val"$"),/end/'

You may use a variable like this:

echo "$x" | awk -vnum=2 '$0 ~ "abc def " num,/end/'

abc def 2
hello there
whats up
end

If abc and end markers must comprise complete line then better to use anchors:

echo "$x" | awk -vnum=2 '$0 ~ "^abc def " num "$",/^end$/'

This will avoid matching line with string abc def 20

If you really have two \n\n between blocks you can use paragraph mode and match the first field:

echo "$x" | awk -v RS= -v FS='\n' -v mark="2" 'match("^abc def " mark "$", $1)'
abc def 2
hello there
whats up
end

You could also use sed here with double quotes to allow the mark variable to be expanded by the shell:

mark=2
echo "$x" | sed -n "/^abc def ${mark}$/,/^end$/p"
Related