Ответы:
В bash с «Расширением параметра» $ {параметр: смещение: длина}
$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d
Изменить: без расширения параметров (не очень элегантно, но это то, что пришло ко мне в первую очередь)
$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r
echo ${var: -2:1}
zsh
и mksh
.
Альтернатива расширению параметра expr substr
substr STRING POS LENGTH
substring of STRING, POS counted from 1
Например:
$ expr substr hello 2 1
e
substr
оно не включено в выражение из FreeBSD, NetBSD или OS X. Это не переносимое решение.
substr
изначально это не расширение GNU. Первоначальная реализация expr
пришла из PWB Unix в конце 70-х и имела substr
(но не :
).
cut -c
Если переменная не содержит символов новой строки, вы можете сделать:
myvar='abc'
printf '%s\n' "$myvar" | cut -c2
выходы:
b
awk substr
это еще одна альтернатива POSIX, которая работает, даже если переменная имеет символы новой строки:
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"
выходы:
b
printf '%s\n'
чтобы избежать проблем с escape-символами: /programming//a/40423558/895245 например:
myvar='\n'
printf '%s\n' "$myvar" | cut -c1
выходы \
как положено.
Смотрите также: /programming/1405611/extracting-first-two-characters-of-a-string-shell-scripting
Проверено в Ubuntu 19.04.
printf '%s' "$myvar" | cut -c2
не POSIX, так как вывод printf
не является текстом, если не $myvar
заканчивается символом новой строки. В противном случае предполагается, что переменная не содержит символов новой строки, так как cut
обрезает каждую строку ввода.
awk
был бы более эффективным и надежным сawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
cut
это не работает для многобайтовых символов (то же самое для mawk или busybox awk)
printf 'abc '| cut -c2
это неправильно, потому что нет \n
(об этом я не знаю), или что команда не выполнится, если у myvar есть новые строки (это я согласен)?
cut
не определено, если ввод не текстовый (хотя cut
реализации требуются для обработки строк или произвольной длины). Вывод printf abc
не является текстом, поскольку он не заканчивается символом новой строки. На практике, в зависимости от реализации, если вы передадите это cut -c2
, вы получите либо ничего b
, b<newline>
либо вообще ничего. Вам нужно printf 'abc\n' | cut -c2
получить поведение, указанное в POSIX (это необходимо для вывода b<newline>
)
С помощью zsh
или yash
вы бы использовали:
$ text='€$*₭£'
$ printf '%s\n' "${text[3]}"
*
(в zsh
, вы можете сократить его до printf '%s\n' $text[3]
).
Вы можете использовать команду вырезать. Чтобы получить 3-е положение:
echo "SAMPLETEXT" | cut -c3
Проверьте эту ссылку http://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html
( Расширенные случаи ) Однако, изменение IFS также является хорошей вещью, особенно когда ваш ввод может содержать пробелы. Только в этом случае используйте приведенный ниже
saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs
IFS
в игру вступит код, который вы опубликовали.