Как я могу удалить все до шаблона и всего после другого шаблона из строки?

В следующем файле:

Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut eu metus id lectus vestibulum ultrices. Maecenas rhoncus.

Я хочу удалить все до consectetuer и все после elit .

Мой желаемый результат:

 consectetuer adipiscing elit. 

Как я могу это сделать?

  • bash escape восклицательный знак внутри переменной с backtick
  • Сохранение вывода команды в переменной оболочки
  • Контрольная переменная в заявлении case bash
  • Как запустить скрипт как ограниченный пользователь?
  • Как создать имя файла для моего приложения электронной почты?
  • Создание дополнительного скрипта копирования и вставки
  • Идиоматический метод bash для запуска необязательного действия без побочных эффектов на код выхода
  • Разрешить пользователям запускать только определенные двоичные файлы с правами root / привилегиями
  • 5 Solutions collect form web for “Как я могу удалить все до шаблона и всего после другого шаблона из строки?”

    Я бы использовал sed

     sed 's/^.*\(consectetuer.*elit\).*$/\1/' file 

    Декодированный сид сид s / find / replace /:

    • s/^.* – заменить начало в начале строки ( ^ ), за которым следует что-нибудь ( .* ) до …
    • \( – запустить именованный блок
    • consectetuer.*elit\. – соответствовать первому слову, всему ( .* ) до последнего слова (в данном случае, включая конечную (экранированную) точку), которую вы хотите сопоставить
    • \) – завершение именованного блока
    • сопоставить все остальное ( .* ) до конца строки ( $ )
    • / – завершите замену раздела поиска
    • \1 – замените блок имен между \( и \) выше
    • / – завершить замену

    Если каждая строка содержит как начальную, так и конечную диаграмму, самый простой способ сделать это – с помощью grep . Вместо того, чтобы удалять начало и конец каждой строки, вы можете просто выводить содержимое между обоими шаблонами. Опция -o в GNU grep выводит только совпадения:

     grep -o 'consectetuer.*elit' file 

    Примечание. Как уже упоминалось, это работает только в том случае, если каждая строка в файле может быть проанализирована таким образом. Опять же, это 80% всех типичных случаев использования.

    Два для петель в AWK:

     $ awk '{for(i=1;i<=NF;i++) {if ($i == "consectetuer") beginning=i; if($i== "elit.") ending=i }; for (j=beginning;j<=ending;j++) printf $j" ";printf "\n" }' file.txt consectetuer adipiscing elit. 

    AWC gsub:

     $ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt consectetuer adipiscing elit. 

    Перл. Это по сути то же самое, что и ответ команды MikeV :

     perl -pe 's/.*(consectetuer.*elit).*./$1/' file 

    « -p означает «печатать каждую строку после применения сценария с -e ». s/foo/bar/ является оператором подстановки; он заменит foo на bar . Скобки фиксируют шаблон и позволяют использовать его в замене. Первый захваченный шаблон – $1 , второй – $2 и так далее.

    Таким образом, команда будет соответствовать всем до consectetuer ( .*consectetuer ), затем все до consectetuer ( .*consectetuer ), а затем все остальное до конца строки ( .* ) И заменит это на захваченный шаблон.

    Я не уверен, почему этот заголовок вопроса был отредактирован « от файла » до « из строки », в то время как OP не исключает возможность на нескольких строках, хотя пример кажется только одной строкой. Независимо от того, что может быть полезно для решения нескольких строк.

    Это работает для перекрестных линий:

     from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2" 

    Примеры:

     [xiaobai@xiaobai tmp]$ cat file 1 abc consectetuer lsl home def elit dd 2 consectetuer ABC elit [xiaobai@xiaobai tmp]$ from1=consectetuer; to2=elit; a="$(cat file)"; a="$(echo "${a#*"$from1"}")"; echo "$from1${a%%"$to2"*}$to2" consectetuer lsl home def elit [xiaobai@xiaobai tmp]$ 

    ссылка: расширение параметра Shell

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