Mam tablicę „opcji” polecenia.
my_array=(option1 option2 option3)
Chcę wywołać to polecenie w skrypcie bash, używając wartości z tablicy jako opcji. Tak więc command $(some magic here with my_array) "$1"
staje się:
command -option1 -option2 -option3 "$1"
Jak mogę to zrobić? Czy to możliwe?
-
na początku każdego słowa wmy_array
?Odpowiedzi:
Wolałbym prosty
bash
sposób:Jednym z powodów tego są spacje. Na przykład, jeśli masz:
Rozwiązania
sed
oparte na tym przekształcą go-option1 -option2 -with -space -option3
(długość 5), ale powyższebash
rozszerzenie przekształci go w-option1 -option2 with space -option3
(długość nadal 3). Rzadko, ale czasami jest to ważne, na przykład:źródło
somevar=("${my_array[@]/#/-}")
(Uwaga nawias wokół wartości). Potem oczywiście trzeba zachować go jako tablicę obsługi podczas korzystania z niego:echo "${somevar[@]}"
. Jeśli chodzi o funkcje, możliwości językowe są zbyt ograniczone. Można przekazać tablicę:somefunc "${my_array[@]/#/-}"
, a następnie wewnątrz trzeba będzie go w$@
:function somefunc() { echo "$@"; }
. Ale to samo$@
będzie zawierało również inne parametry, jeśli istnieje, i nie ma innego sposobu na zwrócenie zmodyfikowanej tablicy niż standardowe wyjście.@
indeksu tablicy? Poddałem go testowi z zsh 5.5.1 i jedyną różnicą, jaką zauważyłem, było to, że zsh prefiksował każdy element, gdy napisano jako${my_array[@]/#/-}
, podczas gdy bash zrobił to również dla*
indeksu dolnego.Nie przetwarzałem, że jest w tablicy i myślałem, że jest oddzielony spacjami w ciągu. To rozwiązanie będzie z tym działało, ale biorąc pod uwagę, że jest to tablica, przejdź do rozwiązania manatwork (
@{my_array[@]/#/-}
).Nie jest tak źle z
sed
podpowłoką. To, jak łatwa jest regex, zależy od tego, co możesz zagwarantować na temat opcji. Jeśli wszystkie opcje to jedno „słowo” (a-zA-Z0-9
tylko), wystarczy prosta początkowa granica słowa (\<
):Jeśli twoje opcje mają inne postacie (najprawdopodobniej
-
), będziesz potrzebować czegoś bardziej złożonego:^
dopasowuje początek wiersza,[ \t]
dopasowuje spację lub tabulator,\|
dopasowuje dowolną stronę (^
lub[ \t]
),\(
\)
grupy (dla\|
) i zapisuje wynik,\<
dopasowuje początek słowa.\1
zaczyna zastępowanie od zachowania pierwszego dopasowania z parens (\(\)
) i-
oczywiście dodaje myślnik, którego potrzebujemy.Działają z gnu sed, jeśli nie działają z twoim, daj mi znać.
A jeśli będziesz używać tej samej rzeczy wiele razy, możesz po prostu obliczyć to raz i zapisać:
źródło
gsed
(zainstalowałem używająchomebrew
). Kolejna rzecz: zamiast tegoecho $my_array
musiałem zrobić,echo ${my_array[@]}
aby uzyskać wszystkie przedmiotymy_array
:echo $my_array
dawałem mi tylko pierwszy element. Ale dzięki za odpowiedź i wyjaśnienie wyrażenia regularnego, szczególnie na temat „granicy słów”, jest to niezwykle przydatne. :)[ $(echo x | sed 's/\</y/') == "yx" ] || exit
.źródło