184 votes

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

J'essaie de produire une chaîne qui contient tout ce qui se trouve entre deux mots d'une chaîne :

l'entrée :

"Here is a String"

sortie :

"is a"

Utilisation :

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

inclut les points de terminaison, mais je ne veux pas les inclure.

26voto

Avinash Raj Points 23485

Grâce à GNU awk,

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

grep avec -P ( perl-regexp ) supporte le paramètre \K ce qui permet d'écarter les caractères précédemment appariés. Dans notre cas, la chaîne précédemment trouvée était Here donc il a été écarté 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

9voto

potong Points 18653

Cela pourrait fonctionner pour vous (GNU sed) :

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

Cela présente chaque représentation de texte entre deux marqueurs (dans ce cas-ci Here y String ) sur une nouvelle ligne et préserve les nouvelles lignes dans le texte.

9voto

Pour comprendre sed nous devons le construire étape par étape.

Voici votre texte original

user@linux:~$ echo "Here is a String"
Here is a String
user@linux:~$ 

Essayons d'enlever Here chaîne avec s ubstition option in sed

user@linux:~$ echo "Here is a String" | sed 's/Here //'
is a String
user@linux:~$ 

A ce stade, je pense que vous pourriez retirer String également

user@linux:~$ echo "Here is a String" | sed 's/String//'
Here is a
user@linux:~$ 

Mais ce n'est pas le résultat souhaité.

Pour combiner deux commandes sed, utilisez -e option

user@linux:~$ echo "Here is a String" | sed -e 's/Here //' -e 's/String//'
is a
user@linux:~$ 

J'espère que cela vous aidera

9voto

Ivan Points 3650

Vous pouvez utiliser deux commandes s

$ echo "Here is a String" | sed 's/.*Here//; s/String.*//'
 is a 

Travaille également

$ echo "Here is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
 is a

$ echo "Here is a StringHere is a StringHere is a StringHere is a String" | sed 's/.*Here//; s/String.*//'
 is a

8voto

Gary Dean Points 93

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é que le mieux était d'écrire une fonction 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"

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X