GNU/Linux >> Znalost Linux >  >> Linux

Asociativní pole ve skriptech Shell?

Viděl jsem trik pro implementaci asociativních polí ve skriptu shellu. Například print array["apples"] může být napsáno jako echo $array$key kde klíč=jablka.

Nebyla zde však žádná zmínka o tom, jak generovat klíče pro iteraci přes pole.
Jediný způsob, jak mě napadl, bylo uložit klíče do proměnné oddělené mezerami, abych mohl k iteraci použít smyčku for přes pole.

Existuje tedy nějaký jiný způsob, jak uložit klíče pro pozdější použití?

Přijatá odpověď:

Skořápky s asociativními poli

Některé moderní shelly poskytují asociativní pole:ksh93, bash ≥4, zsh. V ksh93 a bash, pokud a je asociativní pole, pak "${!a[@]}" je pole jeho klíčů:

for k in "${!a[@]}"; do
  echo "$k -> ${a[$k]}"
done

V zsh tato syntaxe funguje pouze v režimu emulace ksh. Jinak musíte použít nativní syntaxi zsh:

for k in "${(@k)a}"; do
  echo "$k -> $a[$k]"
done

${(k)a} funguje také, pokud a nemá prázdný klíč.

V zsh můžete také zacyklit na obou k eys a v alues ​​ve stejnou dobu:

for k v ("${(@kv)a}") echo "$k -> $v"

Skořápky bez asociativních polí

Emulovat asociativní pole v shellech, které je nemají, je mnohem pracnější. Pokud potřebujete asociativní pole, je pravděpodobně čas přinést větší nástroj, jako je ksh93 nebo Perl.

Pokud potřebujete asociativní pole v pouhém prostředí POSIX, zde je způsob, jak je simulovat, když klíče mohou obsahovat pouze znaky 0-9A-Z_a-z (číslice ASCII, písmena a podtržítko). Za tohoto předpokladu mohou být klíče použity jako součást názvů proměnných. Níže uvedené funkce působí na pole identifikované předponou názvu, „kmenem“, které nesmí obsahovat dvě po sobě jdoucí podtržítka.

## ainit STEM
## Declare an empty associative array named STEM.
ainit () {
  eval "__aa__${1}=' '"
}
## akeys STEM
## List the keys in the associatve array named STEM.
akeys () {
  eval "echo "$__aa__${1}""
}
## aget STEM KEY VAR
## Set VAR to the value of KEY in the associative array named STEM.
## If KEY is not present, unset VAR.
aget () {
  eval "unset $3
        case $__aa__${1} in
          *" $2 "*) $3=$__aa__${1}__$2;;
        esac"
}
## aset STEM KEY VALUE
## Set KEY to VALUE in the associative array named STEM.
aset () {
  eval "__aa__${1}__${2}=$3
        case $__aa__${1} in
          *" $2 "*) :;;
          *) __aa__${1}="${__aa__${1}}$2 ";;
        esac"
}
## aunset STEM KEY
## Remove KEY from the associative array named STEM.
aunset () {
  eval "unset __aa__${1}__${2}
        case $__aa__${1} in
          *" $2 "*) __aa__${1}="${__aa__${1}%%* $2 } ${__aa__${1}#* $2 }";;
        esac"
}

(Varování, netestovaný kód. Detekce chyb pro syntakticky neplatné kmeny a klíče není k dispozici.)

Související:Linux – pomalá média – ladění mezipaměti disku?
Linux
  1. Povolit skripty Setuid On Shell?

  2. Správné zamykání skriptů Shell?

  3. Pole v Unix Bourne Shell?

  1. Spouštět skripty Shell přes web?

  2. Rozšíření souborů pro skripty Unix Shell?

  3. Jak spouštět skripty Pythonu ze shellu

  1. Jak zrušit kořenová oprávnění ve skriptech Shell?

  2. Skrýváte heslo ve skriptech Shell?

  3. Sdílení proměnných ve více skriptech Shell?