Tablice i Tablice Asocjacyjne
Zwykłe Tablicy
arr=(a b)
print -l $arr # a\nb
print -l "$arr" # a b
print -l "${(@)arr}" # a\nb
print -l "${arr[@]}" # a\nb
Operacje binarne na listach:
# cześć współna dwóch list
${arr2:*arr1}
# różnica dwóch list
${arr2:|arr1}
# zastrzeżenia: https://unix.stackexchange.com/questions/104837/intersection-of-two-arrays-in-bash
Filtrowanie tablic:
Odfiltruj wzór glob od tablicy
path=(${path:#*pyenv*})
# filtruj wzór glob od tablicy
local_path=(${(M)path:#/usr/local*})
Rozdzielić wyjście polecenia do tablicy przez LF, repesktując odstępy:
IFS=$'\n' files=($(fd -d1))
# lub
files=("${(f)$(fd -tf)}")
Rozdziel uwzględniając gramatyka powłoki (tj. usuwając zbędne odstępy)
pids=("${(zf)$(ps -A o sid=)}")
Stosując ekspansję na tablic szeregowo, nie wmieszamy konwersję do łańcucha. Zatem
echo ${(F)${cmds%*-15}#llvm-*} | wyst
# zamiast
echo ${${(F)cmds%*-15}#llvm-*} | wyst
Tablice asocjacyjne
typeset -A assoc assoc2
assoc=([ax]=1 [b]=2 [cx]=3 [d]=21 [2]=e)
# wybieranie kluczy/wartości
echo $assoc[(i)*x] # cx
echo $assoc[(I)*x] # cx ax
echo $assoc[(r)2] # 2
echo $assoc[(R)2*] # 2 21
# preciwobraz wartości
echo ${(k)assoc[(R)1]} # ax
echo ${(k)assoc[(R)*1]} # ax d
# ostatni wygrywa
echo ${(kv)assoc[(RI)2]} # 2 e
# iteracja nad tablicą, cudzysłowie oraz @ niezbędne
for k v in "${(@kv)assoc}"; do echo $k $v; done
# splątąć dwa listy do tablicy asocjacyjnej
typeset -A assoc # istotne
assoc=("${(@)arr1:^arr2}")
# "e" znaczy "exact", czyli pasowanie wzoru bez globowania
# czyli, sprawdź obecność argumentu w tablicy
foo () { if (($@[(Ie)-B])); then echo found; else; echo not found; fi }
Globowanie
Filtrować listę przez wzorzec glob:
ls -d ${(R)fpath:#/usr/share*}
Globowanie plików wykonywalnych na $path
echo {^~path}/*(*)
Pochodzenie wszystkich plików wykonywalnych pasujących do globu:
dpkg -S ${^~path}/*virt*(*N:A)| sort
Wiązania symboliczne (ang. symlink
) które wsazują na katalogi:
ll -d /usr/include/**/*(@-/)
Filtrowanie globa za pomocą dowolnego warunku:
ls /usr/bin/*(e:'file $REPLY | grep python >/dev/null':)
glob na tablicę:
arr=(${:-/sys/module/*})
Glob nieuwzględniający wielkość liter. Niektóre kwalifikatory muszą wyprzedzać część wzorca
wl **/(#i)*txt
Kwalifikatory globów tylko na koniec globu. Przykład ekskluzji z kwalifikacją:
ls /usr/share/systemtap/tapset/**/*~*.stp(.)
Uzupełnienia (zshcompsys
)
Jeśli chodzi o załatwianie konfliktów pomiędzy konkurującymi implementacjami uzupełnień dla poszczególnych poleceń, pierwszy wpis w ${FPATH}
w chwili uruchomienie compinit
wygrywa.
_describe
arr=(a b c)
_describe -t tag 'opcja jako lista' arr
_describe -t tag 'opis jako łańcuch' '(a b c)'
_arguments
Specyfikacje opjci jak -f[force]:opis:
oczekuje parametr do argumentu, ale nie daje uzupełnienia. Opcja bez parametru opisujemy przez -f[force]
. Zatem
_arguments \
'-f[force]' \
'1: :_files' \
poprawnie uzupełnia foo -f ^I
oraz foo ^I
.
Szupełnienie pliki pasujące do globa:
_foo () { _arguments '-p[port]:port:_path_files -g /dev/\*\(%c\)' }
Prosta lista zsh
:
local types=(a b c)
_arguments '-t[types]: :($types)' '*: :_default' --
Pliki z Odstępami w Nazwie
Rozdziel standardowe wejście na $@
uwzględniając wiersze z odstępami (np. nazwy plików):
ls -l "${(f)$(fd -tf jakieś.*windowsowe.*pliki)}"
Inne
Znaajdź opcję w liście argumentów $words
i upewnij się że ma powiązany argument
local -i idx=${words[(I)-B]}
if ((idx > 0 && idx + 1 <= $#words )); then
cachefile="${words[((idx+1))]}/CMakeCache.txt"
...
fi
Zarządzanie deskryptorami plików:
exec {myfd} < ./file
while read -u ${myfd} line; do # też read line <&${myfd};
echo ${LINE}
done
exec {myfd}<&-
Przekierować jedynie stderr przez potokę:
LD_DEBUG=all =ls 2>&1 >&- >/dev/null | less
# w odróznieniu od basha, następujące nie działą
LD_DEBUG=all =ls 2>&1 >/dev/null | less
Liczby szesnastkowe - printf nalezy do libc:
echo $'\x41'
printf "%d" 0x41
Moduły
Gniazda TCP
Host 1:
zmodload zsh/net/tcp
ztcp -l 5123 # listen
listenfd=$REPLY
ztcp -a $listenfd # accept
fd=$REPLY
Host 2:
zmodload zsh/net/tcp
ztcp host1 5123
fd=$REPLY