I want to search with grep for a string that looks like this:
something ~* 'bla' I tried this, but the shell removes the single quotes. Argh...
grep -i '"something ~* '[:alnum:]'"' /var/log/syslog What would be the correct search?
If you do need to look for quotes in quotes in quotes, there are ugly constructs that will do it.
echo 'And I said, "he said WHAT?"' works as expected, but for another level of nesting, the following doesn't work as expected:
echo 'She said, "And I said, \'he said WHAT?\'"' Instead, you need to escape the inner single quotes outside the single-quoted string:
echo 'She said, "And I said, '\''he said WHAT?'\''"' Or, if you prefer:
echo 'She said, "And I said, '"'"'he said WHAT?'"'"'"' It ain't pretty, but it works. :)
Of course, all this is moot if you put things in variables.
[ghoti@pc ~]$ i_said="he said WHAT?" [ghoti@pc ~]$ she_said="And I said, '$i_said'" [ghoti@pc ~]$ printf 'She said: "%s"\n' "$she_said" She said: "And I said, 'he said WHAT?'" [ghoti@pc ~]$ :-)
\n is not support by many implementations of echo. It's supported by the built-in echo that bash uses, but it doesn't work in Bourne compatibility mode (i.e. when bash is run as /bin/sh) and it's not there in the echo built in to FreeBSD's tcsh. I recommend that you use printf if you want \n to work consistently. As for your question ... my advice is that you experiment ... or more sage advice would be: If the code is unclear, use different code.\n as anything but the two characters \ and n. Try: bash --posix -c 'echo "one\ntwo"'. I note also that the /bin/echo from coreutils behaves as I would expect. dash, on the other hand, which IIRC is the default sh on Ubuntu, DOES interpret escape sequences when launched as sh. Could it be that you tested with dash?getconf _XOPEN_UNIX tells whether a given system supports XSI, getconf _XOPEN_VERSION reports the XSI version. Both OSX 10.11, Linux 3.x-kernel systems report support. Linux is not officially certified, but OSX is (UNIX 03), which explains why they went out of their way to tweak Bash.grep -i "something ~\* '[[:alnum:]]*'" /var/log/syslog works for me.
* to match a literal * instead of making it the zero-or-more-matches character:~* would match zero or more occurrences of ~ while~\* matches the expression ~* after something:alnum: (see example here)* after [[:alnum::]] to match not only one character between your single quotes but several of them character classes are specified with [[:alnum:]] (two brackets)
[[:alnum:]] is matching only one character. To match zero or more characters [[:alnum:]]*
you can just use " " to quote the regex:
grep -i "something ~\* '[[:alnum:]]*'" /var/log/syslog It seems, as per your expression, that you are using first ', then ". If you want to escape the single quotes, you can either use ' and escape them, or use double quotes. Also, as Matteo comments, character classes have double square brackets. Either:
grep -i "something \~\* '[[:alnum:]]+'" /var/log/syslog or
grep -i 'something ~* \'[[:alnum:]]+\'' /var/log/syslog
'"not just"