Chcę zrobić coś takiego:
foo=( )
foo[0]="bar"
foo[35]="baz"
for((i=0;i<${#foo[@]};i++))
do
echo "$i: ${foo[$i]}"
done
# Output:
# 0: bar
# 1:
Następnie próbowałem przejść przez to za pomocą for:
foo=( )
foo[0]="bar"
foo[35]="baz"
for i in ${foo[@]}
do
echo "?: $i"
done
# Output:
# ?: bar
# ?: naz
ale tutaj nie znam wartości indeksu.
Wiem, że możesz coś takiego
foo=( )
foo[0]="bar"
foo[35]="baz"
declare -p foo
# Output:
# declare -a foo='([0]="bar" [35]="baz")'
ale czy nie możesz tego zrobić w inny sposób?
(a b c)
aby przekonwertować na tablicę.[@]
i podwójne cudzysłowy oznacza, że nie jest to „lista słów oddzielona spacjami”. Otrzymasz listę rzeczywistych kluczy tablicy, nawet jeśli poszczególne klucze zawierają spacje.The use of [@] and double quotes means it's not a "space separated list of words"
"${foo[@]}"
przyjmuje zmienną (tablica)foo
i rozwija ją jako tablicę, zachowując tożsamość swoich elementów, tj. nie dzieląc ich na białe znaki. Jeślifoo=(x 'y z')
, tof "${foo[@]}"
wywołujef
z dwoma argumentamix
i'y z'
. Zapytania o metadane, takie jak"${!foo[@]}"
i"${#foo[@]}"
podobnie, działająfoo
jak tablica."${!foo[@]}"
jest listą wszystkich indeksów ustawionych w tablicy”.zawsze możesz użyć parametru iteracji:
źródło
((ITER++))
in modern bashźródło
W bash 4 możesz używać tablic asocjacyjnych:
W bash 3 to działa (działa również w Zsh):
źródło
źródło
Prosta sztuczka z jednym wierszem do zrzucania tablicy
Dodałem jedną wartość do spacji:
Ja za szybki zrzut grzmotnąćTablice lub tablice asocjacyjne, których używam
To polecenie w jednym wierszu:
Wyrenderuje:
Wyjaśnione
printf "%s\n" "${!foo[@]}"
wypisze wszystkie klucze oddzielone znakiem nowej linii ,printf "%s\n" "${foo[@]}"
wypisze wszystkie wartości oddzielone znakiem nowej linii ,paste <(cmd1) <(cmd2)
scali dane wyjściowecmd1
icmd2
wiersz po wierszu.Tuning
Można to dostroić
-d
przełącznikiem:lub nawet:
Tablica asocjacyjna będzie działać tak samo:
Problem z znakami nowej linii lub znakami specjalnymi
Niestety, co najmniej jeden warunek powoduje, że to już nie działa: gdy zmienna zawiera znak nowej linii:
Polecenie
paste
będzie łączyć wiersz po wierszu, więc dane wyjściowe staną się niepoprawne:Do tej pracy można użyć
%q
zamiast%s
w drugimprintf
poleceniu (i cytowanie):Idealnie sprawdzi się:
Od
man bash
:źródło
printf "%q\n" "${var[@]}"
nową linię był moim problemem!