Jak wyprowadzać ciągi rozdzielane przecinkami za pomocą rozwijania nawiasu klamrowego


17

chciałbym

$ echo a{b,c,d}

aby wyświetlić listę oddzieloną przecinkami, np

ab,ac,ad

zamiast zwykłego wyjścia

ab ac ad

Jak najłatwiej to zrobić w wierszu poleceń?

Odpowiedzi:


9

Zakładając, że elementy nie zawierają spacji, możesz przetłumaczyć spacje na przecinki:

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

który produkuje:

ab,ac,ad

Możesz także używać zakresów ze znakami:

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

Jest to szczególnie przydatne, jeśli chcesz mieć większy zasięg.


13

Wygląda na to, że bash nie używa $ IFS do łączenia wygenerowanych słów. Inną techniką byłoby przechowywanie wygenerowanych słów w tablicy, a następnie $ IFS będzie w grze:

Użyję podpowłoki, więc nie zmieniam IFS tej powłoki: wybierz jedną z

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

To emituje ciąg rozdzielający przecinki na standardowe wyjście. Jeśli chcesz to zrobić:

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

W ogóle nie dołącza do wygenerowanych słów. To jest cały punkt, rozwija się do oddzielnych słów.
Stéphane Chazelas,

5

Jestem pewien, że jest na to wiele sposobów. Oto jedna metoda:

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

2

Rozwiń elementy, które pokazałeś, a następnie zapętl je, dodając przecinek do wszystkich oprócz pierwszej iteracji:

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

Wynik:

ab, ac, ad

Zobacz podstawienie parametrów bash .


1

Oto rozwiązanie tylko dla bash.

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

Część przed średnikiem przypisuje ab ac adsię do zmiennej, INa druga część używa funkcji wyszukiwania i zamiany, aby zmienić wszystkie spacje na przecinki. //Oznacza wszystkie mecze, a nie tylko pierwszego.

Zrób to wszystko w podpowłoce (nawiasach), aby nie zanieczyszczać przestrzeni nazw.


1

Warto zauważyć, że w wielu kontekstach na takiej liście dopuszczalny jest przecinek końcowy. Jeśli akceptowalny jest przecinek końcowy, najłatwiejszym sposobem na zastąpienie jest printf:

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

(Gdzie some-commandjest polecenie, które działa na liście oddzielonej przecinkami i nie dba o przecinek końcowy.)

W rzeczywistości, nawet jeśli nie musisz mieć przecinka, możesz użyć printf; wystarczy podać liczbę argumentów, których się spodziewasz, co sprawia, że ​​jest niezgrabny w przypadku bardzo długich list:

some-command "$(printf %s,%s,%s a{b,c,d} )"
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.