Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sed (in bash) works with [ \t] but not with \s?

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)

like image 575
RocketNuts Avatar asked May 04 '15 11:05

RocketNuts


People also ask

Does sed work in bash?

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.

What is G option in sed?

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.

What does sed mean bash?

Sed, which stands for stream editor, is probably most commonly used to find and replace strings in bash scripts.

What is D in sed?

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.


2 Answers

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:

  • To use (space) and \t together, like you were doing.
  • To use [[:space:]].
like image 137
fedorqui 'SO stop harming' Avatar answered Oct 01 '22 07:10

fedorqui 'SO stop harming'


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, ...)

like image 38
NeronLeVelu Avatar answered Oct 01 '22 07:10

NeronLeVelu