20

I tried to replace multiple spaces in a file to single space using sed.

But it splits each and every character like below. Please let me know what the problem is ...

$ cat test.txt
 iiHi Hello   Hi
this   is   loga

$

$ cat test.txt | tr [A-Z] [a-z]|sed -e "s/ */ /g"
 i i h i h e l l o h i
 t h i s i s l o g a 
codeforester
  • 39,467
  • 16
  • 112
  • 140
logan
  • 7,946
  • 36
  • 114
  • 185
  • Possible duplicate of [How to remove extra spaces in bash?](https://stackoverflow.com/q/13092360/608639) – jww May 26 '19 at 22:46

5 Answers5

28

Your sed command does the wrong thing because it's matching on "zero or more spaces" which of course happens between each pair of characters! Instead of s/ */ /g you want s/ */ /g or s/ +/ /g.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
24

Using tr, the -s option will squeeze consecutive chars to a single one:

tr -s '[:space:]' < test.txt
 iiHi Hello Hi
this is loga

To downcase as well: tr -s '[:space:]' < test.txt | tr '[:upper:]' '[:lower:]'

glenn jackman
  • 238,783
  • 38
  • 220
  • 352
12
sed 's/ \+/ /g' test.txt | tr [A-Z] [a-z]

or

sed 's/\s\+/ /g' test.txt | tr [A-Z] [a-z]

Good grief that was terse, because * matches zero or more it inserted a space after every character, you want + which matches one or more. Also I switched the order because in doing so you don't have to cat the file.

Amos Baker
  • 769
  • 6
  • 13
  • 2
    sed must be with '-r', otherwise regexps would not work `sed -r 's/\s\+/ /g' test.txt` – Temak Nov 23 '20 at 17:00
  • @Temak - that must be dependent on the flavor of sed, with GNU sed 4.4 I did not need the flag. – Amos Baker Dec 16 '20 at 21:03
  • `$ man sed | grep s\/reg -A1 s/regexp/replacement/ Attempt to match regexp against the pattern space. If successful, replace that portion matched with replacement. The replacement may contain the special character & to` – Amos Baker Jun 22 '22 at 20:57
3

You can use awk to solve this:

awk '{$0=tolower($0);$1=$1}1' test.txt
iihi hello hi
this is loga
Jotne
  • 40,548
  • 12
  • 51
  • 55
0

Maybe you can match the following regex for multiple spaces:

'\s+'

and replace with just one space as follows:

' '

sshashank124
  • 31,495
  • 9
  • 67
  • 76