Za pomocą sed usunąć zarówno kwadrat otwierający, jak i zamykający nawias kwadratowy wokół sznurka

19

Uruchamiam to polecenie w powłoce bash na Ubuntu 12.04.1 LTS. Usiłuję usunąć zarówno znaki, jak [i ]znaki za jednym zamachem, tj. Bez konieczności odpuszczania po raz drugi.

Wiem, że nawiasy kwadratowe mają specjalne znaczenie w wyrażeniu regularnym, więc uciekam od nich, poprzedzając je odwrotnym ukośnikiem. Spodziewałem się tylko sznurka, 123ale nawiasy kwadratowe pozostają i chciałbym wiedzieć, dlaczego!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]
Xhantar
źródło
Ostatecznie staram się przypisać cokolwiek między nawiasami kwadratowymi do zmiennej bash, aby użyć jej gdzie indziej w moim skrypcie bash, więc jeśli istnieje lepszy sposób na osiągnięcie tego (używając awk, być może?), Proszę dać mi znać .
Xhantar
2
Tylko dodając jako komentarz: Możesz użyć funkcji bash PE, jak w: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Valentin Bajrami
1
@ val0x00ff - Czyste podstawienie bash .. dzięki! :) Nauczyłem się czegoś nowego.
Xhantar

Odpowiedzi:

25

Jest to łatwe, jeśli dokładnie przestrzegasz instrukcji : wszyscy członkowie klasy postaci tracą specjalne znaczenie (z kilkoma wyjątkami). I] traci swoje specjalne znaczenie, jeśli zostanie umieszczone na liście jako pierwsze . Próbować:

$ echo '[123]' | sed 's/[][]//g'
123
$

To mówi:

  1. wewnątrz zewnętrznych [nawiasów] zamień dowolny z zawartych znaków, a mianowicie:
    • ] i
    • [
  2. zamień dowolny z nich na pusty ciąg - stąd pusty ciąg zastępujący //,
  3. wymieniaj je wszędzie ( globalnie ) - stąd finał g.

Ponownie, ] musi być pierwszy w klasie, ilekroć jest uwzględniony.

Saparagus
źródło
11

Nie jestem pewien, dlaczego to nie działa, ale to działa:

echo '[123]' | sed 's/\(\[\|\]\)//g'

albo to:

echo '[123]' | sed -r 's/(\[|\])//g'

Możesz także wypróbować inne podejście i dopasować ciąg znaków w nawiasach (zakładając, że łańcuch można łatwo dopasować i nie jest zdefiniowany w nawiasach):

echo '[123]' | egrep -o "[0-9]+"

Mam takie same problemy z używaniem oryginalnego wyrażenia regularnego, grepwięc podejrzewam, że to nie tylko sedsprawa.

Dziwnie, dają różne wyniki, ale jeden z nich pasuje do tego, co chcesz:

echo '[123]' | egrep -o '[^][]+'
123

echo '[123]' | egrep -o '[^[]]+'
3]

Zastosowanie tego do oryginału sed(i dodanie /gmodyfikatora, aby usunął oba nawiasy):

echo '[123]' | sed 's/[][]//g'
123
Ladadadada
źródło
Twoje trzecie podejście (egrep -o ...) wygląda jak najczystsze rozwiązanie mojego problemu. Zawsze będę mieć liczby całkowite między nawiasami kwadratowymi (i przepraszam, powinienem wspomnieć o tym w moim pytaniu), więc myślę, że nie powinienem napotykać żadnych dziwactw. Dzięki!
Xhantar
3
Możesz także użyć tr: echo '[123]' | tr -d '[]'- pozwala uniknąć nieporozumień wyrażeń regularnych dotyczących ucieczki.
James O'Gorman
@James O'Gorman - Ciekawe. Z jakiegoś powodu myślałem, że trmoże to przetłumaczyć tylko jeden znak na raz, ale się myliłem. Dzięki!
Xhantar
4

Aby usunąć wszystko przed i po nawiasach:

$ echo '[123]' | sed 's/.*\[//;s/\].*//;'
123

Jeśli Twoje dane są takie, zawsze oznacza to rozpoczynanie i kończenie na nawiasach kwadratowych:

$ echo '[123]' | sed 's/.//;s/.$//;'
123
Guru
źródło
Dane, z którymi pracuję, zawsze zaczynają się i kończą nawiasami kwadratowymi tak. Wciąż chciałbym wiedzieć, dlaczego moje rozwiązanie nie działa. Jakieś pomysły? I czy jest na to sposób bez określania 2x wyrażeń regularnych?
Xhantar
1
@Guru to rozwiązanie zadziałało ode mnie, a jeśli chodzi o Xhantar, to jest bardzo późna odpowiedź, ale to, co widzę w twoim kodzie i przewodniku Bash dla początkujących na tldp.org, próbujesz przeprowadzić wielokrotne wyszukiwanie i zamianę, jedno dla „[” i inne dla „]”, które nie działają, aby rozdzielić dwa różne wyszukiwania i zastąpić, użyj „;” lub opcje -e. 's / <search> / <replace> / g; s / <search> / <replace> / g 'OR sed -e' s / <search> / <replace> / g '-e' s / <search> / <replace> / g '
ArunMKumar
1

Jeśli masz bardziej złożony ciąg, np. „Abcdef [123] ghijk”, możesz również użyć wewnętrznego polecenia bash „cut”, aby wyodrębnić tekst tylko w nawiasach kwadratowych:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123
Valentt
źródło
1

Możesz uciec z klamry otwierającej za pomocą \[. Do klamry zamykającej użyj []].

użytkownik2428118
źródło