Comment utiliser sed/grep pour extraire du texte entre deux mots?

j'essaie de sortir une chaîne qui contient tout entre deux mots d'une chaîne:

entrée:

"Here is a String"

sortie:

"is a"

utilisant:

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

comprend les paramètres, mais je ne veux pas les inclure.

84
demandé sur anishsane 2012-11-06 04:08:45

10 réponses

sed -e 's/Here\(.*\)String//'
72
répondu Brian Campbell 2012-11-06 00:14:09

grep Simple peut également soutenir un regard positif et négatif et un regard en arrière: Pour votre cas, la commande serait:

 echo "Here is a string" | grep -o -P '(?<=Here).*(?=string)'
119
répondu anishsane 2012-11-06 06:58:37

vous pouvez rayer des cordes dans Bash seul:

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

et si vous avez un GNU grep qui inclut PCRE , vous pouvez utiliser une assertion de largeur zéro:

$ echo "Here is a String" | grep -Po '(?<=(Here )).*(?= String)'
is a
30
répondu ghoti 2016-10-20 20:35:38

la réponse acceptée ne supprime pas le texte qui pourrait être avant Here ou après String . Ce sera:

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

la principale différence est l'ajout de .* immédiatement avant Here et après String .

27
répondu wheeler 2017-05-05 03:23:40

par GNU awk,

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

grep avec -P ( perl-regexp ) paramètre prend en charge \K , ce qui aide à rejeter les caractères précédemment appariés. Dans notre cas, la chaîne précédemment appariée était Here donc elle a été écartée de la sortie finale.

$ 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 vous voulez que la sortie soit is a alors vous pouvez essayer ce qui suit,

$ 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
17
répondu Avinash Raj 2014-08-19 15:19:41

si vous avez un long fichier avec de nombreuses ocurrences multilignes, il est utile de commencer par imprimer les lignes du numéro:

cat -n file | sed -n '/Here/,/String/p'
17
répondu alemol 2015-06-05 09:18:25

cela pourrait marcher pour vous (GNU sed):

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

présente chaque représentation de texte entre deux repères (dans ce cas Here et String ) sur une ligne nouvelle et préserve les lignes nouvelles dans le texte.

7
répondu potong 2012-11-06 00:50:37

toutes les solutions ci-dessus présentent des lacunes lorsque la dernière chaîne de recherche est répétée ailleurs dans la chaîne. J'ai trouvé mieux d'écrire une fonction de 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"
4
répondu Gary Dean 2015-06-17 06:19:29

vous pouvez utiliser (se référer à http://www.grymoire.com/Unix/Sed.html#uh-4 ):

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

le contenu qui se trouve à l'intérieur des crochets sera stocké sous la forme .

2
répondu mvairavan 2014-08-19 21:14:36

problème. mes messages stockés sont emballés comme suit, et j'essaie d'extraire les lignes objet:

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: <20171019190902.18741771@VictoriasJourney.com>

Par A2 dans ce fil, Comment utiliser sed/grep pour extraire le texte entre les deux mots? la première expression, ci-dessous, "fonctionne" tant que le texte apparié ne contient pas de nouvelle ligne:

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

[SLC38A9 lysosomal arginine sensor; mTORC1 pathway] Key

cependant, malgré l'essai de nombreuses variantes ( .+?; /s; ...

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

la Solution 1.

Per extrait de texte entre deux chaînes sur des lignes différentes

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

qui donne

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

la Solution 2.*

Per Comment puis-je remplacer une newline (\n) en utilisant sed?

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

remplacera newlines par un espace.

enchaîner avec A2 dans comment utiliser sed/grep pour extraire du texte entre deux mots? , nous obtenons:

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

qui donne

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

cette variante supprime les espaces doubles:

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

donnant

[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]]
0
répondu Victoria Stuart 2017-12-01 22:51:27