I want to search-replace something containing whitespace on a bash command line, and I assumed sed would be the easiest way to go.
Using [ \t]
denoting either tab or space, to match the whitespace, works as intended:
echo "abc xyz" | sed "s/[ \t]xyz/123/"
abc123
But using \s
instead of [ \t]
does not, to my surprise:
echo "abc xyz" | sed "s/\sxyz/123/"
abc xyz
I'm fairly new to bash so I might be missing something trivial, but no matter what I do, I can't get this to work. Using \\s
instead of \s
, using single quotes ('
instead of "
), putting the whitespace marker inside square brackets (like [\s]
or even [\\s]
), nothing seems to help..?
(edit) in case it differs from one sed / bash version to another: I'm working on OS X here.
Additionally, I noticed that when I add a +
after the [ \t]
whitespace part, to optionally grab multiple space/tab characters if present, it doesn't work anymore either...??
echo "abc xyz" | sed "s/[ \t]+xyz/123/"
abc xyz
(and again, also tried with \+
instead of +
, and single quotes instead of double quotes, nothing helps)
Bash allows you to perform pattern replacement using variable expansion like (${var/pattern/replacement}). And so, does sed like this (sed -e 's/pattern/replacement/'). However, there is more to sed than replacing patterns in text files.
Substitution command In some versions of sed, the expression must be preceded by -e to indicate that an expression follows. The s stands for substitute, while the g stands for global, which means that all matching occurrences in the line would be replaced.
Sed, which stands for stream editor, is probably most commonly used to find and replace strings in bash scripts.
It means that sed will read the next line and start processing it. Your test script doesn't do what you think. It matches the empty lines and applies the delete command to them.
As seen in SuperUser's How to match whitespace in sed?:
For POSIX compliance, use the character class [[:space:]] instead of \s, since the latter is a GNU sed extension
So you are probably running a non-GNU sed
version, hence \s
not working to you.
You have two solutions:
(space) and \t
together, like you were doing.[[:space:]]
.echo 'abc xyz<>abcxyz' | sed 's/[[:space:]]xyz/123/g'
abc123<>abcxyz
echo 'abc xyz<>abcxyz' | sed "s/[[:space:]]xyz/123/g"
abc123<>abcxyz
doesn't work on very old sed version but fine on GNU sed as posix complaint (AIX, ...)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With