Come generare stringhe separate da virgole usando l'espansione del controvento bash


17

Mi piacerebbe

$ echo a{b,c,d}

per generare un elenco separato da virgole come

ab,ac,ad

invece del solito output

ab ac ad

Qual è il modo più semplice per farlo dalla riga di comando?

Risposte:


9

Supponendo che gli elementi non contengano spazi, è possibile tradurre gli spazi in virgole:

echo a{b,c,d} | tr ' ' ,

che produce:

ab,ac,ad

Puoi anche usare intervalli con caratteri:

echo a{b..d} | tr ' ' ,

Ciò è particolarmente utile se si desidera una gamma più ampia.


13

Sembra che bash non usi $ IFS per unire le parole generate. Un'altra tecnica sarebbe quella di memorizzare le parole generate in un array e quindi saranno in gioco $ IFS :

Userò una subshell quindi non modifico l'IFS di questa shell: scegline una

( words=( a{b,c,d} ); IFS=,; echo "${words[*]}" )
( set -- a{b,c,d}; IFS=,; echo "$*" )

Ciò emette la stringa separata da virgola su stdout. Se vuoi catturarlo:

joined=$( set -- a{b,c,d}; IFS=,; echo "$*" )

Non unisce affatto le parole generate. Questo è il punto, si espande per separare le parole.
Stéphane Chazelas il

5

Sono sicuro che ci sono molti modi per farlo. Ecco un metodo:

echo a{b,c,d} | sed 's/ /,/g'

2

Espandi gli elementi come mostrato e quindi esegui il ciclo su di essi, aggiungendo la virgola a tutti tranne la prima iterazione:

for i in a{b,c,d}; do
  u="${u:+$u, }$i"
done
echo "$u"

Risultato:

ab, ac, ad

Vedi la sostituzione dei parametri bash .


1

Ecco una soluzione solo per bash.

(IN=$(echo a{b,c,d}); echo ${IN// /,})
# ab,ac,ad

La parte prima del punto e virgola viene assegnata ab ac adalla variabile INe la seconda parte utilizza la ricerca e la sostituzione per modificare tutti gli spazi in virgole. Il //mezzo tutte le partite, non solo la prima.

Fai tutto in una subshell (le parentesi racchiuse) per non inquinare il tuo spazio dei nomi.


1

Vale la pena notare che in molti contesti, una virgola finale è accettabile in tale elenco. Se una virgola finale è accettabile, il modo più semplice per gestire la sostituzione è printf:

some-command "$(printf %s, a{b,c,d} )"

(Dov'è some-commandun comando che viene eseguito su un elenco separato da virgole e non si preoccupa di una virgola finale.)

In realtà, anche se non devi avere una virgola finale puoi usare printf; devi solo specificare il numero di argomenti che ti aspetti, il che lo rende più goffo per elenchi molto lunghi:

some-command "$(printf %s,%s,%s a{b,c,d} )"
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.