Использование cut для возврата середины строки

У меня есть xml-строка, эхо-эха в stdout вдоль строк

 <xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute> 

В этом случае я хочу вернуть строку {41c33a-4893b-3627a-617a} . Я думал об использовании разреза (может быть, даже о том, что это было два раза), но я понятия не имею о правильном синтаксисе. Я использую bash.

4 Solutions collect form web for “Использование cut для возврата середины строки”

Вы можете использовать параметр cut -s -d для определения разделителя (который исключается из полученных полей):

 echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | cut -d\> -f2 | cut -d\< -f1 

Это разделяется на > и выводит второе поле, оставляя {41c33a-4893b-3627a-617a}</xml:attribute , затем снова на < и выводит первое поле.

Поля описывают текст между разделителями и между началом текста и первым разделителем, а также последним разделителем и концом текста. Используя > в исходном тексте, вы получите:

  1. <xml:attribute
  2. {41c33a-4893b-3627a-617a}</xml:attribute
  3. пустая строка

(разделитель опущен). Тогда использование < на поле 2 дает

  1. {41c33a-4893b-3627a-617a}
  2. /xml:attribute

и поле 1 есть результат, который вы ищете.

Для простых строковых манипуляций вы обычно должны использовать собственные конструкции оболочки, связанные с расширением параметра . Внешние утилиты лучше обрабатывают большие объемы текста, но для одной строки запуск внешнего инструмента медленный, и получение права на цитирование может быть затруднено.

 mystring='<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>' content="${mystring#*>}"; content="${content%<*}" braced="${mystring#*\{}"; braced="${braced%%\}*}"; braced="{$braced}" 

content устанавливается на исходную строку минус ведущая и конечная части <…> . braced устанавливается в первую часть, которая выглядит как {…} .

Вы также можете использовать sed чтобы определить поле, заданное регулярным выражением. Полезно, если у вас более сложные критерии соответствия:

 echo '<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>' | \ sed -E 's/^.+>({.+})<.+$/\1/' 

Или с awk , используя regexp <|> как разделитель полей:

 $ echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | awk -F '<|>' '{print $3}' {41c33a-4893b-3627a-617a} 

Примечание: проверено с помощью GNU awk , mawk и original-awk . Работает одинаково во всех трех.

Версия perl очень похожа (за исключением того, что массивы perl основаны на нуле, а инструкция print perl не выводит конечный \n если вы явно не указали это):

 echo "<xml:attribute>{41c33a-4893b-3627a-617a}</xml:attribute>" | perl -n -a -F'<|>' -e 'print $F[2],"\n"' 

Также обратите внимание: это работает только надежно, потому что это одна строка ввода, содержащая один фрагмент XML. Регулярные выражения нельзя использовать для надежного анализа фактического XML. Вместо этого используйте инструмент синтаксического анализа XML, например xmlstarlet или одну из многих XML-синтаксических библиотек для perl , python и других языков.

  • Как сделать svn сохранить учетные данные, когда --non-interactive
  • Как создать псевдоним для последовательности команд?
  • Как я могу предоставить все разрешения для файла для одного пользователя, а не я?
  • Почему компиляция функции ловушки позволяет управлять c-с?
  • Високосный год - экстраполяция
  • Почему SIGKILL не останавливает остановленную программу (да)?
  • Вывод трубы из одной команды в нестандартный ввод другой команды
  • извлечение строк текста из длинного файла
  • Добавить аргументы в bash -c
  • Как использовать переменную оболочки внутри команды sed?
  • Shell отключается при арифметическом выражении в цикле
  • Linux и Unix - лучшая ОС в мире.