Awk, чтобы удалить лишний пробел после первой буквы?

Наш файл содержит:

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

Как получить такой контент:

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

Эта команда awk '{$1=$1} 1' file удаляет все лишние пробелы.
Но нам нужно только убрать лишний пробел после первой буквы.

Кто-нибудь знает?
Мы ценим все ваше внимание!

1
Jeff Schaller 3 Янв 2018 в 02:04
1
Вы имеете в виду после первого слова?
 – 
Jeff Schaller
3 Янв 2018 в 02:27
Да. Нам нужно удалить лишние пробелы после первого слова. Спасибо!
 – 
user62359
3 Янв 2018 в 02:28
Вам нужно конкретно awk? Этот sed сделал бы это: sed -r 's/([^ ]+) +/\1 /' file.
 – 
PesaThe
3 Янв 2018 в 02:50
@PesaThe, посмотри на пример внимательнее. Ваша команда этого не сделает.
 – 
Wildcard
3 Янв 2018 в 03:09
1
@Wildcard, но добавление /g должно заставить его работать, не так ли? Хотя может быть лучше использовать [[:space:]] вместо пробела, на тот случай, если посередине есть вкладки и т. д.
 – 
ilkkachu
3 Янв 2018 в 10:48

3 ответа

Лучший ответ

С помощью GNU awk вы можете:

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

match($0, /(^[ ]+)/, arr) Захват пробелов в начале строки.
$1=$1 удалите все начальные и повторяющиеся пробелы.
printf("%s%s\n", a[1], $0)} снова добавьте начальные пробелы и напечатайте.

1
ImHere 3 Янв 2018 в 05:36

Если вы используете Linux и GNU Sed, вы можете использовать флаг g вместе с номером для команды ssubstitute:

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

Цитирую 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.

Но поскольку в одном случае вы ДЕЙСТВИТЕЛЬНО хотите сделать замену в первом экземпляре пробела (когда нет начальных пробелов), полный ответ (с GNU Sed):

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

Другими словами, добавьте начальный пробел ко всем строкам, затем «выжмите» все экземпляры последовательных пробелов, кроме первого, затем удалите добавленный начальный пробел.


Если ваши начальные пробелы всегда кратны 8, вместо этого вы можете использовать следующую команду, совместимую с POSIX:

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

Или проще:

unexpand file.txt | tr -s ' ' | expand
2
Wildcard 3 Янв 2018 в 03:21

Вот способ KISS сделать это в awk, я думаю:

{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.
0
steeldriver 3 Янв 2018 в 05:13
Вы один из важных людей в этом мире! Спасибо за ваше время!
 – 
user62359
3 Янв 2018 в 08:10