Как сопоставить пробел в sed?

218

Как я могу сопоставить пробелы в sed? В моих данных я хочу сопоставить все 3+ последующих пробельных символа (пробел) и заменить их на 2 пробела. Как это может быть сделано?

Питер Смит
источник

Ответы:

226

Класс символов \sбудет соответствовать пробельным символам <tab>и <space>.

Например:

$ sed -e "s/\s\{3,\}/  /g" inputFile

заменит каждую последовательность не менее чем 3 пробелов двумя пробелами.


ЗАМЕЧАНИЕ : для соответствия POSIX используйте класс символов [[:space:]]вместо \s, так как последний является расширением GNU sed. Смотрите спецификации POSIX для sed и BRE

mrucci
источник
5
Ага! Это был отсутствующий переключатель, который получил меня.
Секвойя Макдауэлл
25
Мне также пришлось добавить ключ -r, который позволяет расширенным регулярным выражениям заставить sed распознавать \ s как пробел.
HUB
39
С Apple sedмне пришлось пользоваться, [[:space:]]потому \sчто у меня не работало. Возможно , \sявляется GNU СЭД расширение?
Джаред Бек
2
@JaredBeck спасибо, у меня заканчивались идеи, почему мое простое регулярное выражение не работало .. Это хромает, я думал, что это стандартное расширенное регулярное выражение .. Также -r не работает и -E сделал присед
Karthik T
3
Вместо этого [[:space:]можно использовать только те, [[:blank:]]которые соответствуют горизонтальным табуляциям и пробелам (но не переводят строки, вертикальные табуляции и т. Д.).
Стефанкт
67

Это работает на MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
некоторые идеи
источник
2
Вы знаете, работает ли это на всех дистрибутивах Linux?
амфибия
2
В общем, GNU sed не будет иметь -E. Со страницы руководства BSD sed: «Опции -E, -a и -i являются нестандартными расширениями FreeBSD и могут быть недоступны в других операционных системах».
Брэд Кох
1
Зачем вам нужен флаг -E для оператора +? Большинство выражений, вероятно, будет в порядке с * вместо этого, тогда это будет работать на других платформах.
Самуил
5
@Samuel Если вы используете *, регулярное выражение будет соответствовать нулю или большему количеству пробелов, и вы получите пробел между каждым символом и пробел в каждом конце каждой строки. Если у вас нет флага -E, вы хотите sed "s/[[:space:]]\+/ /g"сопоставить один или несколько пробелов.
jbo5112
1
FWIW, NetBSD sed также поддерживает этот -Eфлаг.
Макандре
13

Некоторые старые версии sed могут не распознавать \ s как токен, соответствующий пустому пространству. В этом случае вы можете сопоставить последовательность из одного или нескольких пробелов и табуляций с '[XZ] [XZ] *', где X - пробел, а Z - табуляция.

Марникс А. ван Аммерс
источник
1
Так что для особой необходимости здесь, с более старым sed, вы можете сделать: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' inputfile, где X - табуляция, а Z - пробел.
Марникс А. ван Аммерс
10
sed 's/[ \t]*/"space or tab"/'
Zac
источник
2
Гарантируется ли это на любой версии sedлюбой системы? Если нет, то, возможно, стоит упомянуть, где это работает аналогично другим ответам, просто чтобы мы знали ограничения и где это могло не дать ожидаемого результата.
Мокубай
2
Этот RE - то, что я использую, чтобы соответствовать пробелу. Это проще, чем классы символов, просто сопоставить табуляцию или пробел. Он использует только самые основные соглашения регулярных выражений, поэтому он должен работать где угодно с функциональной реализацией регулярных выражений.
конец
3
На Mac 10.9.5 это соответствует пробелам и 't'. Я использовал вышеприведенное указание Майкла Дума для сопоставления пробельных символов (это также работает с -e).
Форма жизни пришельцев
Не работает на моей системе SUSE. Это соответствует первому месту в строке, где есть ноль или более пробелов, что перед первым символом. Я сомневаюсь, что это предназначенная функция, и, конечно, не был запрошенный вариант использования. Я полагаю, что вы хотите изменить '*' для '\ +' (или '\ {3, \}' для вопроса) и, возможно, поставить ag в конце команды sed, чтобы соответствовать всем вхождениям шаблона. Замена [\ t] на [[: space:]] также может быть желательной, если в строке есть что-то еще для пробела.
jbo5112