2012-03-26 17 views
10

Sto provando a scorrere in ogni riga di un file e trovare ed estrarre lettere che iniziano con ${ e terminano con }. Quindi, come output finale, mi aspetto solo SOLDIR e TEMP (da inputfile.sh).Estrarre più occorrenze sulla stessa linea utilizzando sed/regex

Ho provato a utilizzare il seguente script ma sembra corrispondere ed estrae solo la seconda occorrenza del modello TEMP. Ho anche provato ad aggiungere g alla fine, ma non aiuta. Qualcuno potrebbe per favore fammi sapere come abbinare ed estrarre entrambe le occorrenze/multiple sulla stessa linea?

inputfile.sh:

. 
. 
SOLPORT=\`grep -A 4 '\[LocalDB\]' \${SOLDIR}/solidhac.ini | grep \${TEMP} | awk '{print $2}'\` 
. 
. 

script.sh:

infile='inputfile.sh' 
while read line ; do  
    echo $line | sed 's%.*${\([^}]*\)}.*%\1%g' 
done < "$infile" 

risposta

9

Posso proporre unSoluzione?

grep -oP '(?<=\${).*?(?=})' 

utilizza Perl-stile lookaround assertions e partite pigramente nulla tra '${' e '}'.

Nutrire la vostra linea ad esso, ottengo

$ echo "SOLPORT=\`grep -A 4 '[LocalDB]' \${SOLDIR}/solidhac.ini | grep \${TEMP} | awk '{print $2}'\`" | grep -oP '(?<=\${).*?(?=})' 
SOLDIR 
TEMP 
+1

TIL riguardo 'grep -P', grazie. –

+0

Molto utile. Grazie! – noumenon

2

Questo potrebbe funzionare per voi (ma forse solo per la vostra linea di ingresso specifico):

sed 's/[^$]*\(${[^}]\+}\)[^$]*/\1\t/g;s/$[^{$]\+//g' 
+0

Ha funzionato. Grazie. – user1292603

+0

In tal caso, si potrebbe voler accettare la risposta. –

0

Estrazione più corrispondenze da una singola linea utilizzando sed non è così male come ho pensato che sarebbe stato, ma è ancora abbastanza esoterica e difficile da leggere :

$ echo 'Hello ${var1}, how is your ${var2}' | sed -En ' 
    # Replace ${PREFIX}${TARGET}${SUFFIX} with ${PREFIX}\a${TARGET}\n${SUFFIX} 
    s#\$\{([^}]+)\}#\a\1\n# 
    # Continue to next line if no matches. 
    /\n/!b 
    # Remove the prefix. 
    s#.*\a## 
    # Print up to the first newline. 
    P 
    # Delete up to the first newline and reprocess what's left of the line. 
    D 
' 
var1 
var2 

E tutto su una riga:

sed -En 's#\$\{([^}]+)\}#\a\1\n#;/\n/!b;s#.*\a##;P;D' 

Dal POSIX esteso regex non supportano i quantificatori non greedy o inserendo una fuga di nuova riga in un'espressione parentesi Ho usato un carattere BEL (\a) come sentinella alla fine del prefisso anziché una nuova riga. Si potrebbe usare una nuova riga, ma la seconda sostituzione dovrebbe essere il discutibile s#.*\n(.*\n.*)##, che potrebbe comportare una quantità patologica di backtracking da parte del motore regex.

Problemi correlati