skip to Main Content

I want to use grep to filter some lines defined in a bash variable.

If the variable is defined within the "$(cat)", then the result is correct:

test_string=$(cat <<END
hello
world
test
bar hello
END
)

echo -e "$test_string"

filter_string="$(grep "hello" <<< "$test_string")"

echo -e "$filter_string"

Here is the correct output:

# test_string=$(cat <<END
hello
world
test
bar hello
END
)
# echo -e "$test_string"
hello
world
test
bar hello
# filter_string="$(grep "hello" <<< "$test_string")"
# echo -e "$filter_string"
hello
bar hello
# 

But if defined the variable with "n" (use script to join many other strings into a single multiple lines variable), the grep will not work as expected:

test_string="hellonworldntestnbar hello"

echo -e "$test_string"

filter_string="$(grep "hello" <<< "$test_string")"

echo -e "$filter_string"

Here is the wrong output:

# test_string="hellonworldntestnbar hello"
# echo -e "$test_string"
hello
world
test
bar hello
# filter_string="$(grep "hello" <<< "$test_string")"
# echo -e "$filter_string"
hello
world
test
bar hello
# 

How to make grep find command to work with "n" in variable?

Update:

Here is the code for creating the multiple lines variable:

test_string="hello"
test_string="${test_string}nworld"
test_string="${test_string}ntest"
test_string="${test_string}nbar hello"

The content of test_string is dynamical by joining other words from other source.

Update 2: Join two string variables with "n":

other_string="world"

test_string="hello"
test_string+=$'n${other_string}'
test_string+=$'ntest'
test_string+=$'nbar hello'

echo "$test_string"

Here is the output:

hello
${other_string}
test
bar hello

2

Answers


  1. When you declare a variable as test_string="hellonworldntestnbar hello" it stored literal n in the declare variable instead of line breaks.

    Use printf to declare a variable with n embedded like this:

    printf -v test_string '%bn' "hellonworldntestnbar hello"
    

    Or else use $'...' directive like this in bash:

    test_string=$'hellonworldntestnbar hello'
    

    Then use grep:

    filter_string="$(grep "hello" <<< "$test_string")"
    
    # check variable content
    declare -p filter_string
    

    Output:

    declare -- filter_string="hello
    bar hello"
    

    Updated answer:

    test_string="hello"
    test_string+=$'nworld'
    test_string+=$'ntest'
    test_string+=$'nbar hello'
    
    echo "$test_string"
    
    echo '---- output ---'
    filter_string="$(grep "hello" <<< "$test_string")"
    # check variable content
    echo "$filter_string"
    

    Output:

    hello
    world
    test
    bar hello
    ---- output ---
    hello
    bar hello
    
    Login or Signup to reply.
  2. Try like this:

    test_string="
    hello
    world
    test
    bar hello
    "
    
    $ grep hello <<< $test_string 
    hello
    bar hello
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search