Jak dopasować białe znaki w sed?

218

Jak mogę dopasować białe znaki w sed? W moich danych chcę dopasować wszystkie 3+ kolejne białe znaki (tabulator) i zastąpić je 2 spacjami. Jak można to zrobić?

Peter Smit
źródło

Odpowiedzi:

226

Klasa znaków \sbędzie pasować do białych znaków <tab>i <space>.

Na przykład:

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

zastąpi każdą sekwencję co najmniej 3 białych znaków dwiema spacjami.


UWAGA : Aby zachować zgodność z POSIX, użyj klasy znaków [[:space:]]zamiast \s, ponieważ ta ostatnia jest rozszerzeniem GNU sed. Zobacz specyfikacje POSIX dla sed i BRE

mrucci
źródło
5
Aha! Doprowadził mnie brakujący przełącznik -e.
sequoia mcdowell,
25
Musiałem także dodać przełącznik „-r”, który pozwala rozszerzonym wyrażeniom regularnym sprawić, że sed rozpoznaje „s” jako przestrzeń.
HUB
39
Z Apple sedmusiałem korzystać, [[:space:]]ponieważ \snie działało dla mnie. Być może \sjest GNU sed rozszerzenie?
Jared Beck
2
@ Dzięki JaredBeck, zabrakło mi pomysłów, dlaczego mój prosty regex nie działa .. To kiepskie, myślałem, że to standardowy rozszerzony regex .. Również -r nie działa i -E zrobił przysiad
Karthik T
3
Zamiast [[:space:]jednego można użyć, [[:blank:]]który pasuje tylko do poziomych tabulatorów i spacji (ale bez znaków nowej linii, tabulatorów pionowych itp.).
stefanct
67

Działa to w systemie MacOS 10.8:

sed -E "s/[[:space:]]+/ /g"
jakieś pomysły
źródło
2
czy wiesz, czy to działa na wszystkich dystrybucjach Linuksa?
amfibia
2
Nie ogólnie GNU sed nie będzie miał -E. Ze strony podręcznika użytkownika BSD: „Opcje -E, -a i -i są niestandardowymi rozszerzeniami FreeBSD i mogą nie być dostępne w innych systemach operacyjnych.”
Brad Koch
1
Dlaczego potrzebujesz flagi -E dla operatora +? Większość wyrażeń prawdopodobnie byłaby odpowiednia z *, wtedy działałoby to na innych platformach.
Samuel
5
@Samuel Jeśli użyjesz *, wyrażenie regularne będzie pasować do zera lub więcej spacji, a otrzymasz spację między każdym znakiem i spację na każdym końcu każdej linii. Jeśli nie masz flagi -E, chcesz sed "s/[[:space:]]\+/ /g"dopasować jedną lub więcej spacji.
jbo5112
1
FWIW, sed NetBSD obsługuje również -Eflagę.
mcandre
13

Niektóre starsze wersje sed mogą nie rozpoznawać tokenów jako białych znaków. W takim przypadku możesz dopasować ciąg jednej lub więcej spacji i tabulatorów do „[XZ] [XZ] *”, gdzie X to spacja, a Z to tab.

Marnix A. van Ammers
źródło
1
Tak więc dla szczególnej potrzeby tutaj, ze starszym sedem, możesz zrobić: $ sed 's / [XZ] [XZ] [XZ] [XZ] * / / g' gdzie X to tab, a Z to spacja.
Marnix A. van Ammers
10
sed 's/[ \t]*/"space or tab"/'
Zac
źródło
2
Czy to gwarantuje, że będzie działać w dowolnej wersji seddowolnego systemu? Jeśli nie, warto wspomnieć, gdzie działa to w podobny sposób, jak inne odpowiedzi, tak więc znamy ograniczenia i gdzie może to nie przynieść zamierzonego rezultatu.
Mokubai
2
Tego RE używam do dopasowania białych znaków. To jest prostsze niż klasy znaków, aby dopasować tabulator lub spację. Wykorzystuje tylko najbardziej podstawowe konwencje wyrażeń regularnych, więc powinien działać wszędzie z funkcjonalną implementacją wyrażeń regularnych.
Nate,
3
W Mac 10.9.5 odpowiada to spacjom i „t”. Użyłem powyższego Michaela Doumy, aby dopasować znaki białych znaków (działa również z -e).
Alien Life Form
Nie działa rozsądnie w moim systemie SUSE. Dopasowuje pierwsze miejsce w wierszu, w którym jest zero lub więcej spacji, czyli przed pierwszym znakiem. Wątpię, czy jest to zamierzona funkcja, a na pewno nie był to wymagany przypadek użycia. Sądzę, że chcesz zmienić „*” dla „\ +” (lub „\ {3, \}” zgodnie z pytaniem) i być może wstawić znak ag na końcu polecenia sed, aby dopasować wszystkie wystąpienia wzorca. Może być również pożądane zastąpienie [\ t] przez [[: spacja:]], na wypadek, gdyby w linii było coś jeszcze dla białych znaków.
jbo5112