Використовуючи sed, щоб видалити як відкриваючий, так і закриваючий квадратний кронштейн навколо струни


19

Я виконую цю команду в bash оболонці на Ubuntu 12.04.1 LTS. Я намагаюся видалити [і ]символи, і символи одним махом, тобто без необхідності переводити трубку на другий раз.

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

~$ echo '[123]' | sed 's/[\[\]]//'
[123]

Я намагаюся в кінцевому підсумку досягти того, щоб призначити все, що знаходиться між квадратними дужками, баш-змінної для використання в іншому місці мого bash-скрипту, тож якщо є кращий спосіб досягти цього (за допомогою awk, можливо?), Будь ласка, дайте мені знати .
Xhantar

2
Просто додаю як коментар: Ви можете використовувати функцію PE в басі, як: str='[123]'; str1=${str/\[/}; str2=${str1/\]}; echo $str2
Валентин Байрамі

1
@ val0x00ff - Чиста заміна баша .. дякую! :) Дізналися чогось нового.
Xhantar

Відповіді:


25

Це легко, якщо уважно дотримуватися посібника : усі члени класу символів втрачають особливий сенс (за кількома винятками). І] втрачає своє особливе значення, якщо розміщується першим у списку. Спробуйте:

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

Це говорить:

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

Знову ж таки, ] треба бути першим у класі, коли воно включене.


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

Ваш третій підхід (egrep -o ...) виглядає як найчистіше рішення моєї проблеми. У мене колись будуть цілі числа між квадратними дужками (і вибачте, я повинен був це згадати у своєму запитанні), тому я не повинен наштовхуватися на будь-які дивацтва, які я думаю. Спасибі!
Xhantar

3
Ви також можете скористатися tr: echo '[123]' | tr -d '[]'- уникає плутанин із повторним виразком щодо втечі.
Джеймс О'Горман

@James O'Gorman - Цікаво. Чомусь я думав, що trможна перекладати лише один символ максимум за один раз, але я помилявся. Спасибі!
Xhantar

4

Щоб видалити все до і після дужок:

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

Якщо ваші дані подібні, це завжди означає, починаючи і закінчуючи квадратними дужками:

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

Дані, з якими я працюю, завжди починатимуться і закінчуватимуться квадратною дужкою, так. Я все ще хотів би знати, чому моє рішення не працювало. Будь-які ідеї? І чи є спосіб це зробити, не вказуючи 2x регулярні вирази?
Xhantar

1
@Guru це рішення працювало у мене, і що стосується Xhantar, це дійсно пізня відповідь, але те, що я бачу з вашого коду та керівництва для початківців Bash на tldp.org, ви намагалися зробити багаторазовий пошук і заміну, один для '[' та інше для ']', які не працюватимуть, щоб виділити два різні пошукові та заміни, використовуйте ";" або опції -e. 's / <шукати> / <замінити> / г; s / <search> / <replace> / g 'OR sed -e' s / <search> / <заміна> / g '-e' s / <search> / <замінити> / g '
ArunMKumar

1

Якщо у вас є складніший рядок на зразок 'abcdef [123] ghijk', ви також можете використовувати внутрішню команду bash 'cut' для вилучення тексту лише між квадратними дужками:

$ echo 'abcdef[123]ghijk' | cut -d '[' -f 2 | cut -d ']' -f 1
123

1

Ви можете уникнути відкривання кронштейна, використовуючи \[. Для фіксатора скористайтесь []].

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