To set a variable to the literal value
\'\"\(foobar\)'another'[program]\[\$var\]()
using a double-quoted string, you would need to escape each literal backslash and each double quote or dollar sign that would otherwise trigger an expansion.
string="\\'\\\"\\(foobar\\)'another'[program]\\[\\\$var\\]()"
If using a single-quoted string, you only have to care about inserting the single quotes specially:
string='\'"'"'\"\(foobar\)'"'"'another'"'"'[program]\[\$var\]()'
Here, I've opted for breaking out of the single quoted string to add a double quoted single quote for each single quote, i.e. '"'"'
. You could also have used an escaped single quote outside of the single quoted string, i.e. '\''
.
You may also choose to use a quoted here-document if the quoteng becomes too cumbersome:
string=$( cat <<'END'
\'\"\(foobar\)'another'[program]\[\$var\]()
END
)
Note that this would trim off the trailing newline if a newline character was the last character in the string.
Your code then tries to delete all backslashes and single quotes, which does not seem right. Instead, use some tool to extract all instances of \
and the following character:
grep -o '\\.' <<<"$string"
This produces
\'
\"
\(
\)
\[
\$
\]
Or,
grep -o '\\.' <<<"$string" | paste -s -d '\0' -
to reproduce exactly the output in the question.
You could also do this in a loop in bash
directly:
while [[ $string =~ \\. ]]; do
printf '%s\n' "${BASH_REMATCH[0]}"
string=${string#*\\?}
done
or,
while [[ $string =~ '\'. ]]; do
printf '%s\n' "${BASH_REMATCH[0]}"
string=${string#*'\'?}
done
This modifies the value of string
by trimming off the bit up to the next match of a backslash and some other character, for as long as such a character sequence exists in the string. The bit matching the given regular expression is printed in each iteration.
foo
is\'"\(foobar\)'another'[program]\[$var\]()
, there's no\"
sequence in it. You'd need"...\\\"..."
for that.