Как использовать sed/grep для извлечения текста между двумя словами?



Я пытаюсь вывести строку, которая содержит все, что между двумя словами строки:



вход:



"Here is a String"


выход:



"is a"


использование:



sed -n '/Here/,/String/p'


включает конечные точки, но я не хочу их включать.

856   10  

10 ответов:

sed -e 's/Here\(.*\)String//'

простой grep также может поддерживать положительный и отрицательный взгляд вперед и назад: В вашем случае команда будет:

 echo "Here is a string" | grep -o -P '(?<=Here).*(?=string)'

вы можете раздеть строки в Баш:

$ foo="Here is a String"
$ foo=${foo##*Here }
$ echo "$foo"
is a String
$ foo=${foo%% String*}
$ echo "$foo"
is a
$

и если у вас есть GNU grep, который включает PCRE, вы можете использовать утверждение нулевой ширины:

$ echo "Here is a String" | grep -Po '(?<=(Here )).*(?= String)'
is a

принятый ответ не удаляет текст, который может быть до Here или после String. Это будет:

sed -e 's/.*Here\(.*\)String.*//'

главным отличием является добавление .* перед Here и после String.

через GNU awk,

$ echo "Here is a string" | awk -v FS="(Here|string)" '{print }'
 is a 

grep с -P(perl-regexp) параметр поддерживает \K, что помогает в отбрасывании ранее подобранных символов. В нашем случае ранее согласованная строка была Here таким образом, он был отброшен из окончательного вывода.

$ echo "Here is a string" | grep -oP 'Here\K.*(?=string)'
 is a 
$ echo "Here is a string" | grep -oP 'Here\K(?:(?!string).)*'
 is a 

если вы хотите, чтобы выход был is a тогда вы можете попробовать ниже,

$ echo "Here is a string" | grep -oP 'Here\s*\K.*(?=\s+string)'
is a
$ echo "Here is a string" | grep -oP 'Here\s*\K(?:(?!\s+string).)*'
is a

Если у вас есть длинный файл с много Multi-линия случае происшествия, это полезно сначала выведите число строк:

cat -n file | sed -n '/Here/,/String/p'

Это может сработать для вас (GNU sed):

sed '/Here/!d;s//&\n/;s/.*\n//;:a;/String/bb;$!{n;ba};:b;s//\n&/;P;D' file 

Это представляет каждое представление текста между двумя маркерами (в данном случае Here и String) на новой строке и сохраняет новые строки в тексте.

все вышеперечисленные решения имеют недостатки, когда последняя строка поиска повторяется в другом месте строки. Я обнаружил, что лучше всего написать функцию bash.

    function str_str {
      local str
      str="${1#*}"
      str="${str%%*}"
      echo -n "$str"
    }

    # test it ...
    mystr="this is a string"
    str_str "$mystr" "this " " string"

можно использовать (см.http://www.grymoire.com/Unix/Sed.html#uh-4):

echo "Hello is a String" | sed 's/Hello\(.*\)String//g'

содержимое, которое находится внутри скобок, будет сохранено как .

проблема. мои сохраненные почтовые сообщения Claws завернуты следующим образом, и я пытаюсь извлечь строки темы:

Subject: [SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular
 link in major cell growth pathway: Findings point to new potential
 therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is
 Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as
 a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway
 identified [Lysosomal amino acid transporter SLC38A9 signals arginine
 sufficiency to mTORC1]]
Message-ID: <[email protected]>

за A2 в этой теме,как использовать sed/grep для извлечения текста между двумя словами? первое выражение, приведенное ниже, "работает" до тех пор, пока сопоставленный текст не содержит новой строки:

grep -o -P '(?<=Subject: ).*(?=molecular)' corpus/01

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key

однако, несмотря на попытки многочисленных вариантов (.+?; /s; ...), Я не мог получить эти работа:

grep -o -P '(?<=Subject: ).*(?=link)' corpus/01
grep -o -P '(?<=Subject: ).*(?=therapeutic)' corpus/01
etc.

Решение 1.

на извлечение текста между двумя строками на разных строках

sed -n '/Subject: /{:a;N;/Message-ID:/!ba; s/\n/ /g; s/\s\s*/ /g; s/.*Subject: \|Message-ID:.*//g;p}' corpus/01

что дает

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular link in major cell growth pathway: Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]                              

решение 2.*

на как я могу заменить новую строку (\n) с помощью sed?

sed ':a;N;$!ba;s/\n/ /g' corpus/01

будет заменить символы новой строки с пробелом.

цепочка, что с A2 в как использовать sed/grep для извлечения текста между двумя словами?, мы получим:

sed ':a;N;$!ba;s/\n/ /g' corpus/01 | grep -o -P '(?<=Subject: ).*(?=Message-ID:)'

что дает

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular  link in major cell growth pathway: Findings point to new potential  therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is  Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as  a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway  identified [Lysosomal amino acid transporter SLC38A9 signals arginine  sufficiency to mTORC1]] 

этот вариант удаляет двойные пробелы:

sed ':a;N;$!ba;s/\n/ /g; s/\s\s*/ /g' corpus/01 | grep -o -P '(?<=Subject: ).*(?=Message-ID:)'

дав

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key molecular link in major cell growth pathway: Findings point to new potential therapeutic target in pancreatic cancer [mTORC1 Activator SLC38A9 Is Required to Efflux Essential Amino Acids from Lysosomes and Use Protein as a Nutrient] [Re: Nutrient sensor in key growth-regulating metabolic pathway identified [Lysosomal amino acid transporter SLC38A9 signals arginine sufficiency to mTORC1]]

Comments

    Ничего не найдено.