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}
zsh
i 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
substr
nie jest uwzględniony w expr z FreeBSD, NetBSD lub OS X. To nie jest przenośne rozwiązanie.
substr
oryginalnie nie jest to rozszerzenie GNU. Oryginalna implementacja expr
pochodzi 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 -c2
nie jest POSIX, ponieważ wynik printf
nie jest tekstem, chyba że $myvar
kończy się znakiem nowej linii. W przeciwnym razie zakłada, że zmienna nie zawiera znaków nowej linii, ponieważ cut
przecina każdą linię jej danych wejściowych.
awk
był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 -c2
to jest złe, ponieważ nie \n
(o tym nie wiem), czy że polecenie nie powiedzie się, jeśli myvar ma nowe linie (zgadzam się)?
cut
jest określone, jeśli dane wejściowe nie są tekstem (choć cut
implementacje są wymagane do obsługi wierszy lub dowolnej długości). Wynik printf abc
nie 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 -c2
uzyskać zachowanie określone przez POSIX (wymagane do wyjścia b<newline>
)
Z zsh
lub yash
uż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
IFS
by się to grało w opublikowanym kodzie.