2014-11-10 19 views
5

ho una variabile che sembra un po 'come questo:Qual è la shell POSIX equivalente di bash <<<

msg="newton apple tree" 

voglio assegnare ciascuna di queste parole in variabili separate. Questo è facile da fare in bash:

read a b c <<< $msg 

C'è un modo compatto e leggibile per farlo nella shell POSIX?

+0

"bash" sta per "Bourne Again Shell". È una versione più grande, migliore e più veloce di "Bourne Shell". Quindi è improbabile. – Sobrique

+0

Non so come * leggibile * lo consideri, ma equivale a usare una pipe. È una possibilità che hai già rifiutato? – hardmath

+2

Se esistesse un POSIX sh (probabilmente non si intende realmente Bourne - Bourne è una shell degli anni '70, a meno che non si sia su Solaris moderatamente obsoleto, nessuno ha Bourne) equivalente, perché bash avrebbe dovuto introdurre il caratteristica? –

risposta

8

scrivere script idiomatiche, non si può semplicemente guardare ogni elemento di sintassi individuale e provare per trovare un equivalente POSIX. È come tradurre il testo sostituendo ogni singola parola con la sua voce nel dizionario.

Il modo POSIX di suddividere una stringa nota per avere tre parole in tre argomenti, simili ma non identiche a read è:

var="newton apple tree" 

set -f 
set -- $var 
set +f 
a=$1 b=$2 c=$3 

echo "$a was hit by an $b under a $c" 
+0

Potrei farlo funzionare in una funzione per evitare di sovrascrivere il globale '$ @', ma questa è un'ottima soluzione. –

+2

Sovrascrive inutilmente i parametri posizionali; una stringa here è solo una scorciatoia per i documenti here-line, quindi non c'è bisogno di sostituire 'read' con il comando' set'. – chepner

3

Non è bello, ma come soluzione generica, è possibile aggirare questo problema con una named pipe.

Da BashFAQ #24:

mkfifo mypipe 
printf '%s\n' "$msg" >mypipe & 
read -r a b c <mypipe 

printf è più affidabile/meglio specificato di echo; Il comportamento dell'eco varia tra le implementazioni se si dispone di un messaggio contenente solo, ad esempio, -E o -n.


Detto questo, per quello che stai facendo qui, si potrebbe utilizzare l'espansione di parametro:

a=${msg%% *}; msg=${msg#* } 
b=${msg%% *}; msg=${msg#* } 
c=${msg%% *}; msg=${msg#* } 
+0

Penso che sia necessario aggiungere "a b c" invece di linea per renderlo più rilevante per il mio esempio. Ma questa sembra una possibile risposta. – Bitdiot

+0

ah, va bene che sembra meglio. – Bitdiot

+0

Mi piacerebbe darti l'assegno, ma penso che quel tizio abbia una soluzione più elegante. Spero non ti dispiaccia. – Bitdiot

10

Un here stringa è zucchero sintattico per una singola linea qui documento:

$ msg="foo * bar" 
$ read a b c <<EOF 
> $msg 
> EOF 
$ echo "$a" 
foo 
$ echo "$b" 
* 
$ echo "$c" 
bar 
Problemi correlati