1

Awk to remove extra space after first letter?

Our file contains:

Blue    sky.    Nice       weather.
    White cloud.    Bright    sun.
        Cool air. Bla    bla          bla.

How to have the content like this:

Blue sky. Nice weather.
    White cloud. Bright sun.
        Cool air. Bla bla bla.

This command, awk '{$1=$1} 1' file, removes all extra spaces.
But we only need to remove extra space after first letter.

Anyone know?
We appreciate all your attention!

  • 1
    After the first word, you mean? – Jeff Schaller Jan 2 '18 at 23:27
  • Yes. We need remove extra spaces after first word. Thanks! – user62359 Jan 2 '18 at 23:28
  • Do you need awk specifically? This sed would do it: sed -r 's/([^ ]+) +/\1 /' file. – PesaThe Jan 2 '18 at 23:50
  • @PesaThe, look at the example more carefully. Your command won't do it. – Wildcard Jan 3 '18 at 0:09
  • 1
    @Wildcard, but adding /g should make it work, no? Though it might be better to use [[:space:]] instead of just the space, just in case there are tabs in the middle, etc. – ilkkachu Jan 3 '18 at 7:48
1

With GNU awk you can do:

awk '{match($0,/(^[ ]+)/,arr)}; {$1=$1;printf("%s%s\n", arr[1], $0)}' 

match($0, /(^[ ]+)/, arr) Capture the line leading spaces.
$1=$1 remove all leading and repeated spaces.
printf("%s%s\n", a[1], $0)} re-add leading spaces and print.

2

If you are running Linux and have GNU Sed, you can use the g flag along with a number to the substitute command:

sed -r 's/ +/ /g2' file.txt

To quote info sed:

 Note: the POSIX standard does not specify what should happen when
 you mix the `g' and NUMBER modifiers, and currently there is no
 widely agreed upon meaning across `sed' implementations.  For GNU
 `sed', the interaction is defined to be: ignore matches before the
 NUMBERth, and then match and replace all matches from the NUMBERth
 on.

But since in one case you DO want to make the replacement on the first instance of a space (when there are no leading spaces), the full answer (with GNU Sed) is:

sed -r 's/^/ /;s/ +/ /g2;s/^ //' file.txt

In other words, add a leading space to all lines, then "squeeze" all instances of consecutive spaces except the first, then remove the added leading space.


If your leading spaces are always a multiple of 8, then you could instead use the following POSIX compliant command:

unexpand file.txt | sed 's/  */ /g' | expand

Or more simply:

unexpand file.txt | tr -s ' ' | expand
0

Here's a KISS way to do it in awk, I think:

{tmp = substr($0,1,match($0,/[^ \t]/)-1); $1=$1; print tmp""$0}

Ex.

$ awk '{tmp = substr($0,1,match($0,/[^ \t]/)-1); $1=$1; print tmp""$0}' file
Blue sky. Nice weather.
    White cloud. Bright sun.
        Cool air. Bla bla bla.
  • You are one of the important person of this world! Thanks for your time! – user62359 Jan 3 '18 at 5:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.