320

How can I match whitespace in sed? In my data I want to match all of 3+ subsequent whitespace characters (tab space) and replace them by 2 spaces. How can this be done?

6 Answers 6

339

The character class \s will match the whitespace characters <tab> and <space>.

For example:

$ sed -e "s/\s\{3,\}/  /g" inputFile

will substitute every sequence of at least 3 whitespaces with two spaces.


REMARK: For POSIX compliance, use the character class [[:space:]] instead of \s, since the latter is a GNU sed extension. See the POSIX specifications for sed and BREs

11
  • 9
    aha! It was the missing -e switch that got me. Sep 12, 2011 at 14:44
  • 32
    I also had to add '-r' switch which enables extended regex's to make sed recognize '\s' as space.
    – HUB
    May 16, 2012 at 15:12
  • 71
    With Apple's sed I had to use [[:space:]] because \s did not work for me. Perhaps \s is a GNU sed extension?
    – Jared Beck
    Jun 17, 2013 at 23:24
  • 3
    @JaredBeck thanks, was running out of ideas why my simple regex wasnt working.. This is lame, I thought \s was standard extended regex.. Also -r doesnt work and -E did squat
    – Karthik T
    Sep 11, 2013 at 4:58
  • 16
    Instead of [[:space:] one could use [[:blank:]] which does match horizontal tabs and spaces only (but no newlines, vertical tabs etc.).
    – stefanct
    Oct 13, 2017 at 13:10
114

This works on MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
9
  • 3
    do you know if this works on all Linux distros ?
    – amphibient
    Feb 6, 2014 at 17:26
  • 3
    Not generally, GNU sed won't have -E. From the BSD sed man page: "The -E, -a and -i options are non-standard FreeBSD extensions and may not be available on other operating systems."
    – Brad Koch
    Mar 18, 2014 at 21:19
  • 1
    Why do you need the -E flag, for the + operator? Most expressions would probably be fine with * instead, then this would work on other platforms.
    – Samuel
    Mar 21, 2015 at 0:05
  • 7
    @Samuel If you use *, the regex will match zero or more spaces, and you will get a space between every character, and a space at each end of each line. If you don't have the -E flag, then you want sed "s/[[:space:]]\+/ /g" to match one or more spaces.
    – jbo5112
    Jan 20, 2016 at 20:49
  • 1
    FWIW, NetBSD's sed supports the -E flag as well.
    – mcandre
    Dec 29, 2017 at 21:53
16
sed 's/[ \t]*/"space or tab"/'
5
  • 3
    Is this guaranteed to work on any version of sed on any system? If not it might be worth mentioning where this does work in a similar fashion as the other answers, just so we know the limitations and where this might not have the intended result.
    – Mokubai
    Jul 22, 2014 at 20:34
  • 3
    This RE is what I use to match whitespace. It is simpler than character classes just to match tab or space. It uses only the most basic conventions of regular expressions, so it should work anywhere with a functional implementation of regular expressions.
    – Nate
    Oct 18, 2014 at 4:50
  • 4
    On Mac 10.9.5 this matches for spaces and 't'. I used Michael Douma's above to match whitespace chars (it also works with -e). Jul 31, 2015 at 18:32
  • 1
    Doesn't work sensibly on my SUSE system. It matches the first place on the line where there is zero or more spaces, which is before the first character. I doubt that is the intended function, and certainly wasn't the requested use case. I believe you want to change the '*' for '\+' (or '\{3,\}' per the question) and maybe put a g at the end of the sed command to match all occurrences of the pattern. Replacing [ \t] with [[:space:]] may also be desirable as well, in case there is something else for whitespace in the line.
    – jbo5112
    Jan 20, 2016 at 20:59
  • 1
    doesn't work on my macos Catalina Nov 5, 2020 at 19:02
15

Some older versions of sed may not recognize \s as a white space matching token. In that case you can match a sequence of one or more spaces and tabs with '[XZ][XZ]*' where X is a space and Z is a tab.

1
  • 1
    So for the particular need here, with an older sed, you could do: $ sed 's/[XZ][XZ][XZ][XZ]*/ /g' inputfile where X is a tab and Z is a space. Apr 12, 2010 at 15:08
0

None of the above worked for me. Yet I found the simplest answer ever by using awk

user@~[]$ cat /tmp/file
/nospace/in/here
/this/one space
/well/seems we have spaces
user@~[]$ cat /tmp/file |awk 'NF>1'
/this/one space
/well/seems we have spaces
user@~[]$ 
1
  • The OP asked for a solution for sed, not awk.
    – PLG
    Dec 17, 2022 at 19:16
0

I don't know if it can help but I just did that :

MacBook-Pro-van-User:training user$ cat sed.txt

My name is Bob

MacBook-Pro-van-User:training user$ sed s/"My name is Bob"/"My Lastname is Montoya"/g sed.txt

My Lastname is Montoya

I just added "" in the command.

1
  • 1
    Welcome to Super User! Before answering an old question having an accepted answer (look for green ✓) as well as other answers ensure your answer adds something new or is otherwise helpful in relation to them. Here is a guide on How to Answer. There is also a site tour and a help center. Oct 6, 2022 at 17:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .