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

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

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

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

  • Как поймать сигнал в командной строке?
  • Сравнение и добавление файлов на основе полей
  • Сценарий оболочки выполняется по-разному на основе рабочего каталога.
  • Шаблоны оболочки и файлы точек
  • +/- после выполнения задания в фоновом режиме
  • Разрешено ли оболочке оптимизировать бесполезные команды завершения?
  • Интерпретация Backquotes
  • Несоответствие между двумя расширениями
  • 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 и других языков.

    Linux и Unix - лучшая ОС в мире.