Odpowiedzi:
W skrócie z „Rozszerzeniem parametru” $ {parametr: offset: długość}
$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d
Edycja: Bez rozszerzenia parametrów (niezbyt elegancki, ale to, co przyszło do mnie jako pierwsze)
$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r
echo ${var: -2:1}
zshi mksh.
Alternatywą dla rozszerzania parametrów jest expr substr
substr STRING POS LENGTH
substring of STRING, POS counted from 1
Na przykład:
$ expr substr hello 2 1
e
substrnie jest uwzględniony w expr z FreeBSD, NetBSD lub OS X. To nie jest przenośne rozwiązanie.
substroryginalnie nie jest to rozszerzenie GNU. Oryginalna implementacja exprpochodzi z PWB Unix pod koniec lat 70. i miała substr(ale nie :).
cut -c
Jeśli zmienna nie zawiera znaków nowej linii, możesz:
myvar='abc'
printf '%s\n' "$myvar" | cut -c2
wyjścia:
b
awk substr to kolejna alternatywa POSIX, która działa, nawet jeśli zmienna ma znaki nowego wiersza:
myvar="$(printf 'a\nb\n')" # note that the last newline is stripped by
# the command substitution
awk -- 'BEGIN {print substr (ARGV[1], 3, 1)}' "$myvar"
wyjścia:
b
printf '%s\n'jest uniknięcie problemów ze znakami zmiany znaczenia: /programming//a/40423558/895245 np .:
myvar='\n'
printf '%s\n' "$myvar" | cut -c1
wyniki \zgodnie z oczekiwaniami.
Zobacz także: /programming/1405611/extracting-first-two-characters-of-a-string-shell-scripting
Testowane w Ubuntu 19.04.
printf '%s' "$myvar" | cut -c2nie jest POSIX, ponieważ wynik printfnie jest tekstem, chyba że $myvarkończy się znakiem nowej linii. W przeciwnym razie zakłada, że zmienna nie zawiera znaków nowej linii, ponieważ cutprzecina każdą linię jej danych wejściowych.
awkbyłby bardziej wydajny i niezawodny zawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
cut, że nie działa dla znaków wielo-bajtowych (taki sam dla mawk lub BusyBox awk)
printf 'abc '| cut -c2to jest złe, ponieważ nie \n(o tym nie wiem), czy że polecenie nie powiedzie się, jeśli myvar ma nowe linie (zgadzam się)?
cutjest określone, jeśli dane wejściowe nie są tekstem (choć cutimplementacje są wymagane do obsługi wierszy lub dowolnej długości). Wynik printf abcnie jest tekstem, ponieważ nie kończy się znakiem nowego wiersza. W praktyce, w zależności od implementacji, jeśli to zrobisz cut -c2, dostaniesz albo nic b, b<newline>albo wcale. Trzeba by printf 'abc\n' | cut -c2uzyskać zachowanie określone przez POSIX (wymagane do wyjścia b<newline>)
Z zshlub yashużyłbyś:
$ text='€$*₭£'
$ printf '%s\n' "${text[3]}"
*
(w zsh, możesz go skrócić printf '%s\n' $text[3]).
Możesz użyć polecenia cięcia. Aby uzyskać trzecią pozycję:
echo "SAMPLETEXT" | cut -c3
Sprawdź ten link http://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html
( Przypadki zaawansowane ) Jednak modyfikacja IFS jest również dobrą rzeczą, szczególnie gdy twoje dane wejściowe mogą zawierać spacje. Tylko w takim przypadku skorzystaj z poniższego
saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs
IFSby się to grało w opublikowanym kodzie.