2012-11-05 12 views
8

ho il testoestratto multiple catturato gruppi da sed a variabili

abc <THIS> abc <THAT> abc <WHAT> abc 

dove abc è un segnaposto per un'espressione ben definita seguente. Mi piacerebbe estrarre i 3 termini tra parentesi e salvarli in 3 variabili separate. È possibile farlo senza analizzare il testo 3 volte? Fondamentalmente mi piacerebbe catturare e in qualche modo "esportare" più gruppi.

E 'chiaro che posso estrarre uno di loro in questo modo:

VARIABLE=`echo $TEXT | sed "s_abc <\(.*\)> abc <.*> abc <.*> abc_\1_g"` 

Ma è possibile ottenere tutti e 3 di loro senza correre sed 3 volte?

Altre soluzioni (portatili) senza sed sono anche benvenute.

risposta

10

Se ci sono personaggi che si sa sarà non apparire in THIS, THAT o WHAT, allora si può scrivere qualcosa di simile:

IFS=$'\t' read -r VAR1 VAR2 VAR3 \ 
    < <(sed 's/^abc <\(.*\)> abc <\(.*\)> abc <\(.*\)> abc$/\1\t\2\t\3/' \ 
      <<< "$TEXT" 
     ) 

dicendo sed di utilizzare tale separatore nella sua uscita, e read per utilizzare quel separatore nel suo input.

5

Questo potrebbe funzionare per voi (GNU sed & bash):

line='abc <THIS> abc <THAT> abc <WHAT> abc' 
var=($(sed 's/[^<]*<\([^>]*\)>[^<]*/"\1" /g' <<<"$line")) 
echo "first ${var[0]} second ${var[1]} third ${var[2]}" 
first "THIS" second "THAT" third "WHAT" 
+0

Qual è il nome del '$ (foo)' operatore? È simile a '\' foo \ ''? – Jawap

+0

@Jawap vedi [qui] (http://mywiki.wooledge.org/BashFAQ/082). – potong

2

Non c'è bisogno di generare un processo:

var='abc <THIS> abc <THAT> abc <WHAT> abc' 
var1=${var#abc <}   # Remove the leading 'abc <'. 
THIS="${var1%%> abc <*}" # Remove the longest trailing '> abc <*'. 
var2="${var1#*> abc <}" # Remove the shortest leading '*> abc <'. 
THAT="${var2%%> abc <*}" # Remove the longest trailing '> abc <*'. 
var3="${var2#*> abc <}" # Remove the shortest leading '*> abc <'. 
WHAT="${var3%> abc}"  # Remove the trailing '> abc' 
echo "$THIS" 
echo "$THAT" 
echo "$WHAT"