sed 's/ [ ]* / /g'
\_/ | \____/ | |
| | | | \- g=globally (not just one occurence)
| | | |
| | | \- to
| | |
| | \- from
| \- s=substitute
\- program sed
The from part:
/ [ ]* /
| | \- repeated 0-infinite times
| \- group of characters
Including the *, there are 3 quantifiers:
- 0 to infinity
? 0 or 1 times
- 1 to infinity
They normally only refer to the last character, so x* matches x, xxxx and nothing. x? matches 0 or 1 x, + matches x, xx, xxx and so on. But it can match a group of characters like [aeiou]+ or a combination, encapsulated in parens: (foo)*. The first matches iiaiaei, the second foo and foofoo.
A group can be an enumeration [aeiou] or a from-to group: [a-z] or a combination: [0-9a-fA-F:]. If you like to include the minus in the group, you have to put it at the end or beginning: [-,:].
The most used command is probably 's' for substitute. Others are 'd' for delete and 'p' for print.
Patterns are encapsulated between delimiters, normally slash.
Sed works line oriented. If you like to replace one (the first) foo with bar, above command is okay. To replace all, you need 'g' for globally.
Other ways to work with sed invoke line numbers:
sed -n '1,5p' file
-n will not print by default, 1,5p means: print from line 1 to 5.
sed '6,$d' file
This is equivalent. It will delete from line 6 to end.
sed '5q' file
is again the same: quit after line 5.
Typically for sed is, that commands are more easy to write than to read.