Использование sed для удаления открывающей и закрывающей квадратной скобки вокруг строки

18

Я запускаю эту команду в оболочке bash на Ubuntu 12.04.1 LTS. Я пытаюсь удалить [и ]символы, и символы одним махом, т. Е. Без необходимости переадресации к sed во второй раз.

Я знаю, что квадратные скобки имеют особое значение в регулярном выражении, поэтому я избегаю их, добавляя обратную косую черту. Результат, который я ожидал, - это просто строка, 123но квадратные скобки остались, и я хотел бы знать, почему!

~$ echo '[123]' | sed 's/[\[\]]//'
[123]
Xhantar
источник
В конечном итоге я пытаюсь назначить все, что находится в квадратных скобках, переменной bash для использования в другом месте моего сценария bash, поэтому, если есть лучший способ добиться этого (возможно, с помощью awk?), Дайте мне знать ,
Xhantar
2
Просто добавив в качестве комментария: вы можете использовать функцию PE в bash, как в: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Валентина Баджрами
1
@ val0x00ff - чистая замена bash .. спасибо! :) Узнал что-то новое.
Xhantar

Ответы:

24

Это легко, если вы будете тщательно следовать руководству : все члены внутри класса персонажей теряют особое значение (за некоторыми исключениями). И] теряет свое особое значение, если он помещается первым в списке. Пытаться:

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

Это говорит:

  1. внутри внешних [скобок] замените любой из включенных символов, а именно:
    • ] и
    • [
  2. заменить любой из них пустой строкой - отсюда и пустая строка замены //,
  3. заменить их везде ( глобально ) - отсюда и финал g.

Опять же, ] должен быть первым в классе, когда он включен.

Saparagus
источник
11

Я не уверен, почему это не работает, но это работает:

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

или это:

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

Вы также можете попробовать другой подход и сопоставить строку внутри скобок (при условии, что строка может быть сопоставлена ​​легко и не определяется скобками):

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

У меня те же проблемы с вашим оригинальным регулярным выражением, grepпоэтому я подозреваю, что это не просто sedвещь.

Как ни странно, они дают разные результаты, но один из них соответствует тому, что вы хотите:

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

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

Применим это к вашему оригиналу sed(и добавим /gмодификатор, чтобы убрать обе скобки):

echo '[123]' | sed 's/[][]//g'
123
Ladadadada
источник
Ваш третий подход (egrep -o ...) выглядит как самое чистое решение моей проблемы. У меня будут только целые числа между квадратными скобками (и извините, я должен был упомянуть об этом в своем вопросе), поэтому я не должен сталкиваться с какими-либо странностями, как мне кажется. Благодарность!
Xhantar
3
Вы также можете использовать tr: echo '[123]' | tr -d '[]'- избегает путаницы регулярных выражений о побеге.
Джеймс О'Горман
@ Джеймс О'Горман - Интересно. Почему-то я думал, что trмогу перевести только один символ максимум за раз, но я ошибся. Благодарность!
Xhantar
4

Чтобы удалить все до и после скобок:

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

Если ваши данные такие, то это всегда означает начало и конец в квадратных скобках:

$ echo '[123]' | sed 's/.//;s/.$//;'
123
Гуру
источник
Данные, с которыми я работаю, всегда начинаются и заканчиваются квадратной скобкой. Я все еще хотел бы знать, почему мое решение не работало все же. Есть идеи? И есть ли способ сделать это без указания 2x регулярных выражений?
Xhantar
1
@Guru это решение сработало у меня, а что касается Xhantar, это очень запоздалый ответ, но, как я вижу из вашего кода и руководства Bash Beginners на tldp.org, вы пытались выполнить многократный поиск и замену, один для '[' и другое для ']', которые не будут работать, для разнесения двух разных поисков и замены используйте ";" или опции -e. 's / <search> / <replace> / g; s / <search> / <replace> / g 'OR sed -e' s / <search> / <replace> / g '-e' s / <search> / <replace> / g '
ArunMKumar
1

Если у вас есть более сложная строка, такая как 'abcdef [123] ghijk', вы также можете использовать внутреннюю команду bash 'cut', чтобы извлечь текст только в квадратных скобках:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123
valentt
источник
1

Вы можете избежать открывающей скобки, используя \[. Для закрывающей скобки используйте []].

user2428118
источник