Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I want to expand a variable in bash with sed or awk. This variable is an array.

For example, the script must delete strings contained in array. I tried

ARRAY1=(
string1
string2
string3
)

sed -i '/${ARRAY1[@]}/d'  /etc/file

and

ARRAY1=(
string1
string2
string3
)

for i  in ${ARRAY1[@]} ;do sed -i '/$i/d'  /etc/file;done

but none works, sed does not expand the variables.
How can I do this?

share|improve this question
    
the second solution would work if you used "" instead of '' as elbarna said. – Rob Oct 2 '14 at 12:33

With zsh:

array1=(
  string1
  string2
  string3
)
sed -i -e/$^array1/d file

Would delete all the lines that match any of the regex in $array1.

Or you could do (any Bourne-like shell):

regexps='string1
string2
string3'
grep -ve "$regexps" file

Or, to search strings, add the -F:

grep -F -v -e$^array1 # (zsh)

or:

strings='string1
string2
string3'
grep -F -ve "$strings" # (any shell)
share|improve this answer

Found solution, using "" instead of ''.

share|improve this answer
1  
It is true that "" will expand your variable for illustration try echo ${ARRAY1[@]}, echo '${ARRAY1[@]}' and echo "${ARRAY1[@]}" ... That said, just changing the quotes would not create the desired behavior as it would also print each element of the array in a separate lines and would at best not match what you intended at worse garble the sed command where it would cause a parsing error of the pattern. – Rob Oct 2 '14 at 12:29

I would not use sed instead use egrep -i -v (-i case insensitive -v does not match pattern):

egrep -i -v "$(echo ${ARRAY1[@]} | tr ' ' '|')" /etc/file

the expression

echo ${ARRAY1[@]} 

because it has no quotes will not print new line making a space delimited string with all the strings in the array.

tr ' ' '|'

will replace all spaces with \| (or) for the grep expression which will build the pattern for your grep command.

Now if you insist on using sed there are a couple of options one of which would look something like:

 sed -i $(echo ${ARRAY1[@]} | sed -e 's:\w\+:-e "/\1/d":g') /etc/file

This will create a separate -e "/stringFromArray/d" for the sed base sed command

NOTE: make sure that there are no spaces or "/$|" in the strings in your array. If there are depending on what solution you try it could get in the way.

share|improve this answer
2  
tr ' ' '\|' does not replace spaces by \|` but by `. tr` replaces characters, not strings. Not quoting ${ARRAY1[@]} is fundamentally problematic as it will break if there is whitespace or \[?* in any of the array elements. While the fundamental idea of using grep here is good, the execution needs to be rethought. – Gilles Oct 2 '14 at 20:59
    
Good point I was in a hurry and grep does not interpret | properly but egrep or grep -E does. so changed it to egrep and the tr to replace space with | and voila. – Rob Oct 3 '14 at 1:51

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.