Vu ici un moyen d'utiliser sed pour get du text entre deux autres strings d'une ligne, comme:
sed 's/.*starting_text\(.*\)ending_text.*/\1/'
mais je voudrais une simple command (comme tr
, mais pour l'extraction de string) qui a juste pris deux cordes et couperait tout avant la première corde ou après la deuxième corde, par exemple
grep something some_file | between message\"\:\" " with"
et gérerait les caractères qui s'échappent.
Si les délimiteurs peuvent apparaître plusieurs fois par lignes, vous pouvez utiliser perl à la place:
between() { perl -Tlne 'BEGIN{$b=shift;$e=shift} print for /\Q$b\E(.*?)\Q$e\E/g' "$@" }
Et puis par exemple:
$ echo "[b]test[e] foo [b]bar[e]" | between '[b]' '[e]' test bar
Vous pouvez également l'utiliser comme:
between BEG END file1 file2...
Pour ce faire, dans sed génériquement, il faudrait des caractères d'échappement dans l'expression rationnelle utilisée pour find la sous-string que j'ai trouvée ici (note: plus d'infos ici si vous rencontrez des problèmes).
Ensuite, j'ai trouvé comment canaliser dans une fonction ici .
Mettre tout cela set dans une fonction que je peux utiliser dans mon .bashrc
, ressemble (bien que je ne doive pas définir les vars a et b, mais cela rend la lecture plus facile):
between(){ a=$(printf '%s\n' "$1"|sed 's![\*.^$/[]!\\&!g') b=$(printf '%s\n' "$2"|sed 's![\*.^$/[]!\\&!g') sed "s/.*$a\(.*\)$b.*/\1/" }
comme Joseph R. l'a mentionné, cette réponse montre comment utiliser grep -oP pour faire similaire. Pour échapper à l'expression rationnelle Perl, j'ai trouvé cela , alors peut-être que les choses suivantes fonctionneraient aussi:
between(){ a=$(printf '%s\n' "$1"|sed 's![]\*.^+?(){|$[]!\\&!g') b=$(printf '%s\n' "$2"|sed 's![]\*.^+?(){|$[]!\\&!g') grep -oP "(?=$a).*?(?=$b)" }