Як зіставити пробіли в sed?


218

Як я можу зіставити пробіли в sed? У своїх даних я хочу зіставити всі 3+ наступних символів пробілу (пробіл) і замінити їх на 2 пробіли. Як це можна зробити?

Відповіді:


226

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

Наприклад:

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

замінить кожну послідовність щонайменше 3 пробілів на два пробіли.


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


5
ага! Мене дістало відсутнє перемикач -e.
секвойя mcdowell

25
Я також повинен був додати перемикач '-r', який дозволяє розширеним регулярним вираженням зробити sed визнавати '\ s' простором.
HUB

39
З Apple, sedя повинен був використовувати, [[:space:]]тому що \sвін не працював для мене. Можливо \s, розширення sed GNU ?
Джаред Бек

2
@JaredBeck спасибі, не вистачало ідей, чому мій простий регекс не працював .. Це кульгавий, я думав, що це стандартний розширений регекс .. Також -r не працює і -E зробив присідання
Karthik T

3
Замість [[:space:]одного можна використовувати те, [[:blank:]]що відповідає лише горизонтальним вкладкам і пробілам (але немає нових рядків, вертикальних вкладок тощо).
stefanct

67

Це працює на MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"

2
чи знаєте ви, чи працює це на всіх дистрибутивах Linux?
амфібій

2
Як правило, у GNU sed не буде -E. На сторінці користувача BSD: "Параметри -E, -a та -i є нестандартними розширеннями FreeBSD і можуть бути недоступні для інших операційних систем."
Бред Кох

1
Навіщо потрібен прапор -E для оператора +? Більшість виразів, мабуть, буде добре з * замість цього, тоді це буде працювати на інших платформах.
Самуїл

5
@Samuel Якщо ви використовуєте *, регулярний вираз буде відповідати нулю або більше пробілів, і ви отримаєте пробіл між кожним символом та пробілом на кожному кінці кожного рядка. Якщо у вас немає прапора -E, ви хочете sed "s/[[:space:]]\+/ /g"відповідати одному або більше пробілів.
jbo5112

1
FWIW, sedBS NetBSD також підтримує -Eпрапор.
mcandre

13

Деякі старіші версії sed можуть не розпізнавати \ s як маркер білого простору, що відповідає. У цьому випадку ви можете зіставити послідовність одного або декількох пробілів і вкладок з '[XZ] [XZ] *', де X - пробіл, а Z - вкладка.


1
Отже, для особливої ​​потреби тут, зі старшим sed, ви можете зробити: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' inputfile, де X - вкладка, а Z - пробіл.
Marnix A. van Ammers

10
sed 's/[ \t]*/"space or tab"/'

2
Чи гарантовано це працювати в будь-якій версії sedбудь-якої системи? Якщо ні, то, можливо, варто згадати, де це працює аналогічно, як інші відповіді, просто ми знаємо обмеження і де це може не мати наміченого результату.
Мокубай

2
Цей RE - це те, що я використовую для відповідності пробілу. Простіше, ніж класи символів, просто відповідати вкладці або пробілу. Він використовує лише найосновніші конвенції регулярних виразів, тому він повинен працювати де завгодно з функціональною реалізацією регулярних виразів.
Нейт

3
На Mac 10.9.5 це збігається з пробілами та 't'. Я використав вищевказаний Майкл Дума, щоб відповідати символам пробілів (він також працює з -e).
Форма життя інопланетян

Не працює розумно в моїй системі SUSE. Він відповідає першому місці в рядку, де є нуль або більше пробілів, що є перед першим символом. Я сумніваюся, що це призначена функція, і, звичайно, це не було запитуваним випадком використання. Я вважаю, що ви хочете змінити "*" на "\ +" (або "\ {3, \}" за запитання) і, можливо, поставити ag в кінці команди sed, щоб відповідати всім явищам шаблону. Заміна [\ t] на [[: space:]] також може бути бажаною, якщо у рядку є щось інше для пробілу.
jbo5112
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.