varios usar una subcadena script regulares reemplazar patrones extraer expresiones eliminar con caracteres cadena buscar archivos string bash sed grep

string - una - ¿Cómo usar sed/grep para extraer texto entre dos palabras?



sed linux (10)

A través de GNU awk,

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

grep con parámetro -P ( perl-regexp ) admite /K , lo que ayuda a descartar los caracteres coincidentes previamente. En nuestro caso, la cadena coincidente previamente estaba Here por lo que se descartó de la salida final.

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

Si quieres que la salida sea is a entonces puedes probar la siguiente,

$ 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

Estoy intentando dar salida a una cadena que contiene todo entre dos palabras de una cadena:

entrada:

"Here is a String"

salida:

"is a"

Utilizando:

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

incluye los puntos finales, pero no quiero incluirlos.


Esto podría funcionar para usted (GNU sed):

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

Esto presenta cada representación de texto entre dos marcadores (en este caso Here y String ) en una nueva línea y preserva las nuevas líneas dentro del texto.


Grep simple también puede admitir look-ahead y look-back positivos y negativos: para su caso, el comando sería:

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


La respuesta aceptada no elimina el texto que podría estar antes de Here o después de String . Esta voluntad:

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

La principal diferencia es la adición de .* Inmediatamente antes de Here y después de String .



Puedes desnudar cadenas solo en Bash :

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

Y si tiene un grep de GNU que incluye PCRE , puede usar una aserción de ancho cero:

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


Si tiene un archivo largo con muchas ocurrencias de varias líneas, es útil imprimir primero las líneas numéricas:

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


Todas las soluciones anteriores tienen deficiencias en las que la última cadena de búsqueda se repite en otra parte de la cadena. Me pareció mejor escribir una función bash.

function str_str { local str str="${1#*${2}}" str="${str%%$3*}" echo -n "$str" } # test it ... mystr="this is a string" str_str "$mystr" "this " " string"


Problema. Mis mensajes de Claws Mail almacenados se envuelven de la siguiente manera, y estoy tratando de extraer las líneas de Asunto:

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

Por A2 en este hilo, ¿Cómo usar sed / grep para extraer texto entre dos palabras? la primera expresión, a continuación, "funciona" siempre que el texto coincidente no contenga una nueva línea:

grep -o -P ''(?<=Subject: ).*(?=molecular)'' corpus/01 [SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key

Sin embargo, a pesar de probar numerosas variantes ( .+?; /s; ... ), no pude hacer que funcionaran:

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

Solución 1.

Por Extraer texto entre dos cadenas en diferentes líneas

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

lo que da

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

Solución 2. *

¿Cómo puedo reemplazar una nueva línea (/ n) usando sed?

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

reemplazará las nuevas líneas con un espacio.

Encadenando eso con A2 en Cómo usar sed / grep para extraer texto entre dos palabras? , obtenemos:

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

lo que da

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

Esta variante elimina espacios dobles:

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

dando

[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 -e ''s/Here/(.*/)String//1/''