sed замінити всі вкладки та пробіли одним простором


23

У мене вийшло такий рядок:

test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

тепер я хочу замінити всі вкладки / пробіли між записами лише одним пробілом, щоб я міг легко ним користуватися cut -d " "

Я спробував таке:

sed "s/[\t[:space:]]+/[:space:]/g"

і різних варіацій, але не вдалося працювати. Якісь ідеї?


Спробуйте: sed -r -e "s / [\ t \] + / / g"
RJS

Чи cutпідтримує ваш -wваріант?
Кондібас

Відповіді:


40

Використовуйте sed -e "s/[[:space:]]\+/ /g"

Ось пояснення:

[   # start of character class

  [:space:]  # The POSIX character class for whitespace characters. It's
             # functionally identical to [ \t\r\n\v\f] which matches a space,
             # tab, carriage return, newline, vertical tab, or form feed. See
             # https://en.wikipedia.org/wiki/Regular_expression#POSIX_character_classes

]   # end of character class

\+  # one or more of the previous item (anything matched in the brackets).

Для заміни потрібно лише вставити пробіл. [:space:]не буде працювати там, оскільки це абревіатура для класу символів, а движок регулярних виразів не знає, який символ туди поставити.

+Повинні бути екрановані в регулярному виразі , тому що з СЄПН регулярних виразів +є нормальним характер , тоді як \+це метасимволом для «один або більше». На сторінці 86 « Освоєння регулярних виразів» Джефрі Фрідл в примітці зазначає, що редактор і греп використовували втечені дужки, оскільки «Кен Томпсон вважав, що регулярні вирази будуть використовуватися для роботи в основному з кодом С, де необхідність узгодження сирих дужок буде більш поширеною, ніж зворотна посилання. . " Я припускаю, що він ставився так само і до знаку плюс, звідси необхідність уникати його, щоб використовувати його як метахарактер. Це легко спокуситись.

У СЕД вам потрібно бігти +, ?, |, (, і ). або використовувати -r, щоб використовувати розширений регулярний вираз (тоді це виглядає як sed -r -e "s/[[:space:]]\+/ /g"абоsed -re "s/[[:space:]]\+/ /g"


Це також видаляє вкладки? Чи можете ви пояснити, чому ви використовуєте \+замість просто +?
Зулакіс

Добре, я розумію. [[: space:]] дорівнює [\ t \ r \ n \ v \ f]. Але ви можете пояснити, чому ви користуєтесь\+
Zulakis

3
[[: space:]] еквівалентно '\ s', тому коротша версія - "s / \ s \ + / / g"
3molo

2
Основні регулярні вирази використовують зворотну косу рису перед знаком плюс, коли використовується для позначення "один або кілька попередніх символів або групи", джерело developer.apple.com/library/mac/#documentation/opensource/… .
3molo

Ах, я розумію! Я не знав, що існують різні версії зразків. Спасибі
Zulakis

6

Ви можете скористатися параметром -s("стиснути") tr:

$ tr -s '[:blank:]' <<< 'test.de.          1547    IN      SOA     ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600'
test.de. 1547 IN SOA ns1.test.de. dnsmaster.test.de. 2012090701 900 1000 6000 600

Клас [:blank:]символів містить як пробіли, так і вкладки.


-2

Мені подобається використовувати наступний псевдонім для bash. Спираючись на те, що написали інші, використовуйте sed для пошуку та заміни кількох пробілів одним простором. Це допомагає отримати стійкі результати від скорочення. Наприкінці я ще раз запускаю його через sed, щоб змінити простір на вкладку, щоб було легше читати.

alias ll='ls -lh | sed "s/ \+/ /g" | cut -f5,9 -d" " | sed "s/ /\t/g"'

Як це відповідає на запитання?
Тонін
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.