Search code examples
bashawkgrep

how to find two lines of strings in bash with awk or grep


This is a sample of data.txt:

"line1":"text1",
"line2":"text2",
"line3":"text3",
"line4":"text4",
"line5":"text5",
"line6":"text6",
"line7":"text7",
"line8":"text8",
"line9":"text9",
"line10":"text10"

This is a very simple data, but I'm trying to do this:

file line `"line7":"text7",\n"line8":"text8",` and three lines before that, and save two variables that I can use in my bash:

content_of_line4='text4'
content_of_lint5='text5'

What I think can be done is something like this:

content_of_line4="$(the_awk_or_grep_command)"
content_of_lint5="$(the_awk_or_grep_command)"

What I tried so far:

grep -E "\"line7\":\"text7",\n\"line8\":\"text8\"," -B3 data.txt

As soon as I add \n\"line8\":\"text8\",, the grep finds nothing. If I remove this, it shows.

I need to use the two variables in my bash commands in the future, so I need to store them.


Solution

  • Your input looks like the "inner part" of a JSON object. If so, you could add the "missing" curly braces, and use jq to extract the fields needed. Example:

    content_of_line4="$(jq -Rsr '"{\(.)}" | fromjson.line4' input.txt)"
    echo "$content_of_line4"
    
    text4
    

    For better reusability, you can also employ the --arg option to use values from the shell for the field name:

    content_of_line5="$(jq -Rsr --arg f "line5" '"{\(.)}" | fromjson[$f]' input.txt)"
    echo "$content_of_line5"
    
    text5