I have a large file ~/foo.txt. Thousands of lines of the form


are scattered throughout the file where X and Y are integers. My problem is that sometimes the integers X and Y are separated by two spaces and sometimes they are separated by one space. I would like to write a perl script that makes the spacing consistent, preferably with two spaces. How could I go about this?

  • Must it be sed? In bash I would do "tr -s " " < ~/foo.txt > dest.txt" for one spacing. Dec 2, 2015 at 7:23
  • This works, I suppose, but there are other instances of consecutive spaces in the file that I would like to preserve, if possible. Dec 2, 2015 at 7:26
  • I don't really care about the tool to be honest. I just assumed perl would be good for this. Dec 2, 2015 at 7:31

3 Answers 3


You say integers, but I suspect you mean positive numbers. Here is a rough quick attempt at a solution:

sed 's/\([0-9]\+\)\s\+\([0-9]\+\)/\1  \2/g'

There are caveats here, such as if the second number starts with a negative sign, or if there are spaces you don't want handled like this that occur between, for instance, a53 and 27B. Or if you don't want all numbers to be separated by two spaces. But this is a start that you can modify as you will.

Rereading your question, it appears that all of the spaces you want to "squeeze" occur specifically on lines starting with the word "SIZE". This makes it much simpler. You say "other instances of consecutive spaces" you want to preserve, but it sounds like those are on other lines. So in that case just use:

sed '/^SIZE/ s_\s\s\+_  _'

(There are two spaces in the replacement text.)

Rereading again, I now see you want to fix one space to two spaces. This gets a bit more dependent on the exact format of your lines, but I would say:

sed '/^SIZE/ s_\s\+_  _3'

should do it. (It works on the sample you provide.) The 3 makes the substitution only occur on the 3rd match of \s\+ - which, as chaos explained, means "one or more space or tab". So in SIZE<space>:<space>X<space>Y, it will turn the space in between the X and Y into two spaces.

  • Yes. Obviously, I started at least 14 seconds later... =) Anyway +1, but no need for the g.
    – chaos
    Dec 2, 2015 at 7:34
  • Thank you and good point. I upvoted yours; good for including the full explanation, I tend to get lazy about that.
    – Wildcard
    Dec 2, 2015 at 7:40

With sed:

sed -i 's/\([0-9]\)\s\+\([0-9]\)/\1  \2/' file
  • -i edits the file inplace.
  • [0-9]: seaches for a digit.
  • \s+: this digit is followed by a space or tab.
  • [0-9]: and again followed by a digit.
  • \1 \2 those two digits are saved in the backreferences \1 and \2 which are now separated by two spaces.


$ cat file
SIZE : 2  1 # 2 spaces
SIZE : 1 22 # 1 space
SIZE : 1    1 # 4 spaces
SIZE : 324  34 # a tab
SIZE : 324      34 # 2 tabs
$ sed 's/\([0-9]\)\s\+\([0-9]\)/\1  \2/' file
SIZE : 2  1
SIZE : 1  22
SIZE : 1  1
SIZE : 324  3
SIZE : 324  34
  • Ah! Ninja'd by 13 seconds. :)
    – Wildcard
    Dec 2, 2015 at 7:32
sed 's/\([0-9] \) *\([-+.]*[0-9]\)/\1 \2/g' <in >out

You must log in to answer this question.

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