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

17

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

Lorem Ipsum Dolor Sit Amet, посвященный Aditiscing Elit. Ut eu metus id lectus vestibulum ultrices. Меценатский хрип

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

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

consectetuer adipiscing elit.

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

Мануэл
источник
2
Команда может быть sed. Это также может быть perlили даже чистый удар.
Муру
@manuel Если один из этих ответов решил вашу проблему, пожалуйста, найдите время и примите его , нажав на флажок слева. Это пометит вопрос как ответивший и выразит благодарность на сайтах Stack Exchange.
Тердон

Ответы:

27

Я бы использовал Сед

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

Декодировал sed s / find / replace / синтаксис:

  • s/^.*- заменить начало в начале строки ( ^), затем что-либо ( .*) до ...
  • \( - начать именованный блок
  • consectetuer.*elit\.- сопоставить первое слово, все ( .*) до последнего слова (в данном случае, включая конечную (экранированную) точку), которую вы хотите сопоставить
  • \) - завершить указанный блок
  • сопоставить все остальное ( .*) до конца строки ( $)
  • / - закончить замену найти раздел
  • \1- заменить на имя блока между \(и \)выше
  • / - закончить замену
MikeV
источник
1
Хороший ответ, но вам не нужен ^или, $так как sed попытается найти самый длинный матч. Также вы, возможно, пропустили точку после elit, вы можете вставить \.при необходимости.
Asoundmove
2
@asoundmove Хороший улов на задней точке "элит". - у тебя довольно острый глаз! Я обновил свой ответ, чтобы включить в шаблон экранированную точку. Вы также правы, что это ^и $не нужно - я оставил их там, поскольку спрашивающий отметил (изначально), что он был немного новичком, и это может быть полезно в других контекстах.
MikeV
Я всегда вставлял скопированные sed-решения и взламывал их, чтобы соответствовать моим потребностям, но благодаря этому ответу я чувствую, что я действительно понимаю это сейчас. Отличный ответ
Тайлер
7

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

grep -o 'consectetuer.*elit' file

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

slebetman
источник
1

Две петли в 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.

AWK в gsub:

$ awk '{gsub(/^.*consectetuer/,"consectetuer"); gsub(/elit.*$/,"elit.");print}' file.txt
consectetuer adipiscing elit.
Сергей Колодяжный
источник
1

Perl способ. По сути, это то же самое, что иsed ответ MikeV :

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

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

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

Тердон
источник
1

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

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

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]$ 

ссылка: Расширение параметров оболочки

林果 皞
источник
1
Отлично!
Клеман