Tablice asocjacyjne w skryptach powłoki
Potrzebowaliśmy skryptu, który symuluje Tablice asocjacyjne lub mapę podobną do struktury danych do skryptów powłoki, dowolnego ciała?
17 answers
Aby dodać do odpowiedź Irfana , Oto krótsza i szybsza wersja get()
, ponieważ nie wymaga iteracji nad treścią Mapy:
get() {
mapName=$1; key=$2
map=${!mapName}
value="$(echo $map |sed -e "s/.*--${key}=\([^ ]*\).*/\1/" -e 's/:SP:/ /g' )"
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 10:31:12
Inną opcją, jeśli przenośność nie jest twoim głównym problemem, jest użycie tablic asocjacyjnych wbudowanych w powłokę. To powinno działać w bash 4.0 (dostępne teraz na większości głównych dystrybucji, ale nie na OS X, chyba że zainstalujesz go samodzielnie), ksh i zsh:
declare -A newmap
newmap[name]="Irfan Zulfiqar"
newmap[designation]=SSE
newmap[company]="My Own Company"
echo ${newmap[company]}
echo ${newmap[name]}
W zależności od powłoki, może być konieczne wykonanie typeset -A newmap
zamiast declare -A newmap
, lub w niektórych może to nie być wcale konieczne.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-28 15:15:29
Inny sposób bez bash 4.
#!/bin/bash
# A pretend Python dictionary with bash 3
ARRAY=( "cow:moo"
"dinosaur:roar"
"bird:chirp"
"bash:rock" )
for animal in "${ARRAY[@]}" ; do
KEY=${animal%%:*}
VALUE=${animal#*:}
printf "%s likes to %s.\n" "$KEY" "$VALUE"
done
echo -e "${ARRAY[1]%%:*} is an extinct animal which likes to ${ARRAY[1]#*:}\n"
Możesz też wrzucić tam oświadczenie if za przeszukanie. if [[$var = ~ / blah/]]. albo cokolwiek.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-15 17:21:12
Myślę, że musisz się cofnąć i pomyśleć o tym, czym naprawdę jest mapa lub tablica asocjacyjna. Wszystko to jest sposób, aby zapisać wartość dla danego klucza i odzyskać tę wartość szybko i skutecznie. Możesz również chcieć mieć możliwość iteracji nad kluczami, aby pobrać każdą parę wartości klucza lub usunąć klucze i powiązane z nimi wartości.
Teraz pomyśl o strukturze danych, której używasz cały czas w skryptach powłoki, a nawet tylko w powłoce bez pisania skryptu, która ma te właściwości. Zakłopotany? To system plików.
Naprawdę, wszystko, czego potrzebujesz, aby mieć tablicę asocjacyjną w programowaniu powłoki, to katalog tymczasowy. mktemp -d
jest konstruktorem tablicy asocjacyjnej:
prefix=$(basename -- "$0")
map=$(mktemp -dt ${prefix})
echo >${map}/key somevalue
value=$(cat ${map}/key)
Jeśli nie masz ochoty używać echo
i cat
, zawsze możesz napisać kilka małych wrapperów; te są wzorowane na Irfanach, chociaż po prostu wypisują wartość zamiast ustawiać dowolne zmienne, takie jak $value
:
#!/bin/sh
prefix=$(basename -- "$0")
mapdir=$(mktemp -dt ${prefix})
trap 'rm -r ${mapdir}' EXIT
put() {
[ "$#" != 3 ] && exit 1
mapname=$1; key=$2; value=$3
[ -d "${mapdir}/${mapname}" ] || mkdir "${mapdir}/${mapname}"
echo $value >"${mapdir}/${mapname}/${key}"
}
get() {
[ "$#" != 2 ] && exit 1
mapname=$1; key=$2
cat "${mapdir}/${mapname}/${key}"
}
put "newMap" "name" "Irfan Zulfiqar"
put "newMap" "designation" "SSE"
put "newMap" "company" "My Own Company"
value=$(get "newMap" "company")
echo $value
value=$(get "newMap" "name")
echo $value
Edit: takie podejście jest rzeczywiście dość nieco szybsze niż wyszukiwanie liniowe przy użyciu sed sugerowanego przez pytającego, a także bardziej wytrzymałe(pozwala na to, aby klucze i wartości zawierały -,=, spację, qnd": SP:"). Fakt, że korzysta on z systemu plików, nie czyni go wolnym; pliki te nigdy nie są gwarantowane, że zostaną zapisane na dysku, chyba że wywołasz sync
; dla plików tymczasowych, takich jak ten o krótkim czasie życia, nie jest mało prawdopodobne, że wiele z nich nigdy nie zostanie zapisanych na dysku.
Zrobiłem kilka benchmarków kodu Irfana, Jerry ' ego modyfikacja kodu Irfana i mojego kodu za pomocą następującego programu sterownika:
#!/bin/sh
mapimpl=$1
numkeys=$2
numvals=$3
. ./${mapimpl}.sh #/ <- fix broken stack overflow syntax highlighting
for (( i = 0 ; $i < $numkeys ; i += 1 ))
do
for (( j = 0 ; $j < $numvals ; j += 1 ))
do
put "newMap" "key$i" "value$j"
get "newMap" "key$i"
done
done
Wyniki:
$ time ./driver.sh irfan 10 5 real 0m0.975s user 0m0.280s sys 0m0.691s $ time ./driver.sh brian 10 5 real 0m0.226s user 0m0.057s sys 0m0.123s $ time ./driver.sh jerry 10 5 real 0m0.706s user 0m0.228s sys 0m0.530s $ time ./driver.sh irfan 100 5 real 0m10.633s user 0m4.366s sys 0m7.127s $ time ./driver.sh brian 100 5 real 0m1.682s user 0m0.546s sys 0m1.082s $ time ./driver.sh jerry 100 5 real 0m9.315s user 0m4.565s sys 0m5.446s $ time ./driver.sh irfan 10 500 real 1m46.197s user 0m44.869s sys 1m12.282s $ time ./driver.sh brian 10 500 real 0m16.003s user 0m5.135s sys 0m10.396s $ time ./driver.sh jerry 10 500 real 1m24.414s user 0m39.696s sys 0m54.834s $ time ./driver.sh irfan 1000 5 real 4m25.145s user 3m17.286s sys 1m21.490s $ time ./driver.sh brian 1000 5 real 0m19.442s user 0m5.287s sys 0m10.751s $ time ./driver.sh jerry 1000 5 real 5m29.136s user 4m48.926s sys 0m59.336s
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-02 19:33:58
hput () {
eval hash"$1"='$2'
}
hget () {
eval echo '${hash'"$1"'#hash}'
}
hput France Paris
hput Netherlands Amsterdam
hput Spain Madrid
echo `hget France` and `hget Netherlands` and `hget Spain`
$ sh hash.sh
Paris and Amsterdam and Madrid
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-30 00:12:16
####################################################################
# Bash v3 does not support associative arrays
# and we cannot use ksh since all generic scripts are on bash
# Usage: map_put map_name key value
#
function map_put
{
alias "${1}$2"="$3"
}
# map_get map_name key
# @return value
#
function map_get
{
alias "${1}$2" | awk -F"'" '{ print $2; }'
}
# map_keys map_name
# @return map keys
#
function map_keys
{
alias -p | grep $1 | cut -d'=' -f1 | awk -F"$1" '{print $2; }'
}
Przykład:
mapName=$(basename $0)_map_
map_put $mapName "name" "Irfan Zulfiqar"
map_put $mapName "designation" "SSE"
for key in $(map_keys $mapName)
do
echo "$key = $(map_get $mapName $key)
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-28 15:28:24
Bash4 wspiera to natywnie. Nie używaj grep
LUB eval
, są najbrzydszymi hackami.
Aby uzyskać szczegółową odpowiedź z przykładowym kodem zobacz: https://stackoverflow.com/questions/3467959
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:54:50
Teraz odpowiadam na to pytanie.
Następujące Skrypty symulują tablice asocjacyjne w skryptach powłoki. To proste i bardzo łatwe do zrozumienia.
Map to nic innego jak niekończący się ciąg znaków, który ma keyValuePair zapisany jako --name = Irfan --design=SSE --company=My: SP: Own:SP: Company
Spacje zastępuje się": SP: "dla wartości
put() {
if [ "$#" != 3 ]; then exit 1; fi
mapName=$1; key=$2; value=`echo $3 | sed -e "s/ /:SP:/g"`
eval map="\"\$$mapName\""
map="`echo "$map" | sed -e "s/--$key=[^ ]*//g"` --$key=$value"
eval $mapName="\"$map\""
}
get() {
mapName=$1; key=$2; valueFound="false"
eval map=\$$mapName
for keyValuePair in ${map};
do
case "$keyValuePair" in
--$key=*) value=`echo "$keyValuePair" | sed -e 's/^[^=]*=//'`
valueFound="true"
esac
if [ "$valueFound" == "true" ]; then break; fi
done
value=`echo $value | sed -e "s/:SP:/ /g"`
}
put "newMap" "name" "Irfan Zulfiqar"
put "newMap" "designation" "SSE"
put "newMap" "company" "My Own Company"
get "newMap" "company"
echo $value
get "newMap" "name"
echo $value
Edit: dodałem kolejną metodę do pobrania wszystkich kluczy.
getKeySet() {
if [ "$#" != 1 ];
then
exit 1;
fi
mapName=$1;
eval map="\"\$$mapName\""
keySet=`
echo $map |
sed -e "s/=[^ ]*//g" -e "s/\([ ]*\)--/\1/g"
`
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-04-14 08:11:06
Dla Bash 3, jest szczególny przypadek, który ma ładne i proste rozwiązanie:
Jeśli nie chcesz obsługiwać wielu zmiennych lub klucze są po prostu nieprawidłowymi identyfikatorami zmiennych, i Twoja tablica ma gwarancję, że będzie miała mniej niż 256 pozycji , możesz nadużywać wartości zwracanych przez funkcję. Rozwiązanie to nie wymaga żadnej podshell, ponieważ wartość jest łatwo dostępna jako zmienna, ani żadnej iteracji, tak aby wydajność krzyczała. Również jest bardzo czytelny, prawie jak Bash 4 wersja.
Oto najbardziej podstawowa wersja:
hash_index() {
case $1 in
'foo') return 0;;
'bar') return 1;;
'baz') return 2;;
esac
}
hash_vals=("foo_val"
"bar_val"
"baz_val");
hash_index "foo"
echo ${hash_vals[$?]}
Pamiętaj, używaj pojedynczych cudzysłowów w case
, w przeciwnym razie podlega globbingowi. Naprawdę przydatne dla statycznych / zamrożonych hashów od samego początku, ale można napisać generator indeksów z tablicy hash_keys=()
.
Uważaj, domyślnie jest to pierwsza, więc możesz chcieć odstawić element zerowy:
hash_index() {
case $1 in
'foo') return 1;;
'bar') return 2;;
'baz') return 3;;
esac
}
hash_vals=("", # sort of like returning null/nil for a non existent key
"foo_val"
"bar_val"
"baz_val");
hash_index "foo" || echo ${hash_vals[$?]} # It can't get more readable than this
Zastrzeżenie: długość jest teraz Niepoprawna.
Alternatywnie, jeśli chcesz zachować indeksowanie oparte na 0, możesz zarezerwować inny wartość indeksu i Ochrona przed nieistniejącym kluczem, ale jest mniej czytelny:
hash_index() {
case $1 in
'foo') return 0;;
'bar') return 1;;
'baz') return 2;;
*) return 255;;
esac
}
hash_vals=("foo_val"
"bar_val"
"baz_val");
hash_index "foo"
[[ $? -ne 255 ]] && echo ${hash_vals[$?]}
Lub, aby długość była prawidłowa, przesunięcie indeksu o jeden:
hash_index() {
case $1 in
'foo') return 1;;
'bar') return 2;;
'baz') return 3;;
esac
}
hash_vals=("foo_val"
"bar_val"
"baz_val");
hash_index "foo" || echo ${hash_vals[$(($? - 1))]}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-03-03 16:15:01
Możesz używać dynamicznych nazw zmiennych i pozwolić, aby nazwy zmiennych działały jak klucze hashmapy.
Na przykład, jeśli Masz plik wejściowy z dwoma kolumnami, nazwa, kredyt, jak w poniższym przykładzie, i chcesz zsumować dochód każdego użytkownika:
Mary 100
John 200
Mary 50
John 300
Paul 100
Paul 400
David 100
Komenda poniżej podsumuje wszystko, używając zmiennych dynamicznych jako kluczy, w postaci map_${person}:
while read -r person money; ((map_$person+=$money)); done < <(cat INCOME_REPORT.log)
Aby przeczytać wyniki:
set | grep map
Wyjście będzie:
map_David=100
map_John=500
map_Mary=150
map_Paul=500
Te techniki, rozwijam na Githubie funkcję, która działa tak samo jak obiekt HashMap, shell_map .
W celu utworzenia instancji " HashMap" funkcja shell_map jest w stanie tworzyć swoje kopie pod różnymi nazwami. Każda nowa kopia funkcji będzie miała inną zmienną $FUNCNAME. $FUNCNAME jest następnie używane do tworzenia przestrzeni nazw dla każdej instancji Mapy.
Klucze map są zmiennymi globalnymi, w postaci $FUNCNAME_DATA_ $ KEY, gdzie $KEY jest kluczem dodanym do mapy. Zmienne te są zmiennymi dynamicznymi .
Poniżej podam jego uproszczoną wersję, abyś mógł użyć jej jako przykładu.
#!/bin/bash
shell_map () {
local METHOD="$1"
case $METHOD in
new)
local NEW_MAP="$2"
# loads shell_map function declaration
test -n "$(declare -f shell_map)" || return
# declares in the Global Scope a copy of shell_map, under a new name.
eval "${_/shell_map/$2}"
;;
put)
local KEY="$2"
local VALUE="$3"
# declares a variable in the global scope
eval ${FUNCNAME}_DATA_${KEY}='$VALUE'
;;
get)
local KEY="$2"
local VALUE="${FUNCNAME}_DATA_${KEY}"
echo "${!VALUE}"
;;
keys)
declare | grep -Po "(?<=${FUNCNAME}_DATA_)\w+((?=\=))"
;;
name)
echo $FUNCNAME
;;
contains_key)
local KEY="$2"
compgen -v ${FUNCNAME}_DATA_${KEY} > /dev/null && return 0 || return 1
;;
clear_all)
while read var; do
unset $var
done < <(compgen -v ${FUNCNAME}_DATA_)
;;
remove)
local KEY="$2"
unset ${FUNCNAME}_DATA_${KEY}
;;
size)
compgen -v ${FUNCNAME}_DATA_${KEY} | wc -l
;;
*)
echo "unsupported operation '$1'."
return 1
;;
esac
}
Użycie:
shell_map new credit
credit put Mary 100
credit put John 200
for customer in `credit keys`; do
value=`credit get $customer`
echo "customer $customer has $value"
done
credit contains_key "Mary" && echo "Mary has credit!"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-05-04 16:51:32
Uznałem, że prawdą jest, jak już wspomniano, że najlepszą metodą jest zapisanie key / vals do pliku, a następnie użycie grep/awk do ich pobrania. Brzmi to jak wszelkiego rodzaju niepotrzebne IO, ale pamięć podręczna dysku działa i sprawia, że jest niezwykle wydajna-znacznie szybciej niż próba przechowywania ich w pamięci za pomocą jednej z powyższych metod (jak pokazują benchmarki).
Oto szybka, czysta metoda, którą lubię:
hinit() {
rm -f /tmp/hashmap.$1
}
hput() {
echo "$2 $3" >> /tmp/hashmap.$1
}
hget() {
grep "^$2 " /tmp/hashmap.$1 | awk '{ print $2 };'
}
hinit capitols
hput capitols France Paris
hput capitols Netherlands Amsterdam
hput capitols Spain Madrid
echo `hget capitols France` and `hget capitols Netherlands` and `hget capitols Spain`
Jeśli chcesz wymusić pojedynczą wartość na klucz, możesz również wykonać mała akcja grep/sed w hput ().
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-09 17:19:59
Jaka szkoda, że wcześniej nie widziałem pytania-napisałem bibliotekę shell-framework , która zawiera m.in. mapy (tablice asocjacyjne). Ostatnią jego wersję można znaleźć tutaj .
Przykład:
#!/bin/bash
#include map library
shF_PATH_TO_LIB="/usr/lib/shell-framework"
source "${shF_PATH_TO_LIB}/map"
#simple example get/put
putMapValue "mapName" "mapKey1" "map Value 2"
echo "mapName[mapKey1]: $(getMapValue "mapName" "mapKey1")"
#redefine old value to new
putMapValue "mapName" "mapKey1" "map Value 1"
echo "after change mapName[mapKey1]: $(getMapValue "mapName" "mapKey1")"
#add two new pairs key/values and print all keys
putMapValue "mapName" "mapKey2" "map Value 2"
putMapValue "mapName" "mapKey3" "map Value 3"
echo -e "mapName keys are \n$(getMapKeys "mapName")"
#create new map
putMapValue "subMapName" "subMapKey1" "sub map Value 1"
putMapValue "subMapName" "subMapKey2" "sub map Value 2"
#and put it in mapName under key "mapKey4"
putMapValue "mapName" "mapKey4" "subMapName"
#check if under two key were placed maps
echo "is map mapName[mapKey3]? - $(if isMap "$(getMapValue "mapName" "mapKey3")" ; then echo Yes; else echo No; fi)"
echo "is map mapName[mapKey4]? - $(if isMap "$(getMapValue "mapName" "mapKey4")" ; then echo Yes; else echo No; fi)"
#print map with sub maps
printf "%s\n" "$(mapToString "mapName")"
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-03 09:08:32
Shell nie ma wbudowanej mapy jak struktura danych, używam raw string do opisywania takich elementów:
ARRAY=(
"item_A|attr1|attr2|attr3"
"item_B|attr1|attr2|attr3"
"..."
)
Gdy wyodrębnia elementy i ich atrybuty:
for item in "${ARRAY[@]}"
do
item_name=$(echo "${item}"|awk -F "|" '{print $1}')
item_attr1=$(echo "${item}"|awk -F "|" '{print $2}')
item_attr2=$(echo "${item}"|awk -F "|" '{print $3}')
echo "${item_name}"
echo "${item_attr1}"
echo "${item_attr2}"
done
To wydaje się nie mądre niż odpowiedź innych ludzi, ale łatwe do zrozumienia dla nowych ludzi do skorupy.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-08-05 08:38:09
Zmodyfikowałem rozwiązanie Wadima następująco:
####################################################################
# Bash v3 does not support associative arrays
# and we cannot use ksh since all generic scripts are on bash
# Usage: map_put map_name key value
#
function map_put
{
alias "${1}$2"="$3"
}
# map_get map_name key
# @return value
#
function map_get {
if type -p "${1}$2"
then
alias "${1}$2" | awk -F "'" '{ print $2; }';
fi
}
# map_keys map_name
# @return map keys
#
function map_keys
{
alias -p | grep $1 | cut -d'=' -f1 | awk -F"$1" '{print $2; }'
}
Zmiana polega na map_get, aby zapobiec zwracaniu błędów, jeśli poprosisz o klucz, który nie istnieje, chociaż efektem ubocznym jest to, że będzie on również po cichu ignorował brakujące mapy, ale lepiej pasował do mojego przypadku użycia, ponieważ chciałem tylko sprawdzić klucz, aby pominąć elementy w pętli.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-11 14:22:16
Kilka lat temu napisałem bibliotekę skryptów dla Basha, która obsługiwała tablice asocjacyjne między innymi (logowanie, pliki konfiguracyjne, rozszerzone wsparcie dla argumentów linii poleceń, generowanie pomocy, Testowanie jednostek, itp.). Biblioteka zawiera wrapper dla tablic asocjacyjnych i automatycznie przełącza się na odpowiedni model (wewnętrzny dla bash4 i emulować dla poprzednich wersji). Został nazwany shell-framework i hostowany w origo.ethz.ch ale dziś zasób jest zamknięty. Jeśli ktoś jeszcze tego potrzebuje Mogę się tym z Tobą podzielić.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-13 12:38:12
Późna odpowiedź, ale rozważ rozwiązanie problemu w ten sposób, używając wbudowanego w bash read , Jak pokazano w poniższym fragmencie kodu ze skryptu zapory ufw. To podejście ma tę zaletę, że używa się tak wielu rozdzielonych zestawów pól (nie tylko 2), Jak jest to pożądane. Wykorzystaliśmy | delimiter, ponieważ specyfikatory zakresu portów mogą wymagać dwukropka, czyli 6001:6010.
#!/usr/bin/env bash
readonly connections=(
'192.168.1.4/24|tcp|22'
'192.168.1.4/24|tcp|53'
'192.168.1.4/24|tcp|80'
'192.168.1.4/24|tcp|139'
'192.168.1.4/24|tcp|443'
'192.168.1.4/24|tcp|445'
'192.168.1.4/24|tcp|631'
'192.168.1.4/24|tcp|5901'
'192.168.1.4/24|tcp|6566'
)
function set_connections(){
local range proto port
for fields in ${connections[@]}
do
IFS=$'|' read -r range proto port <<< "$fields"
ufw allow from "$range" proto "$proto" to any port "$port"
done
}
set_connections
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-15 16:58:41
Dodanie innej opcji, jeśli jq jest dostępny:
export NAMES="{
\"Mary\":\"100\",
\"John\":\"200\",
\"Mary\":\"50\",
\"John\":\"300\",
\"Paul\":\"100\",
\"Paul\":\"400\",
\"David\":\"100\"
}"
export NAME=David
echo $NAMES | jq --arg v "$NAME" '.[$v]' | tr -d '"'
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-13 20:11:25