Respuestas:
En bash con "Expansión de parámetros" $ {parámetro: desplazamiento: longitud}
$ var=abcdef
$ echo ${var:0:1}
a
$ echo ${var:3:1}
d
Editar: Sin expansión de parámetros (no muy elegante, pero eso fue lo primero que me vino)
$ charpos() { pos=$1;shift; echo "$@"|sed 's/^.\{'$pos'\}\(.\).*$/\1/';}
$ charpos 8 what ever here
r
echo ${var: -2:1}
zsh
y mksh
.
La alternativa a la expansión de parámetros es expr substr
substr STRING POS LENGTH
substring of STRING, POS counted from 1
Por ejemplo:
$ expr substr hello 2 1
e
substr
no está incluido en el expr de FreeBSD, NetBSD u OS X. Esta no es una solución portátil.
substr
originalmente no es una extensión GNU. La implementación original expr
de PWB Unix vino a finales de los 70 y tenía substr
(pero no :
).
cut -c
Si la variable no contiene nuevas líneas, puede hacer:
myvar='abc'
printf '%s\n' "$myvar" | cut -c2
salidas:
b
awk substr
es otra alternativa POSIX que funciona incluso si la variable tiene nuevas líneas:
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"
salidas:
b
printf '%s\n'
es para evitar problemas con los caracteres de escape: /programming//a/40423558/895245 por ejemplo:
myvar='\n'
printf '%s\n' "$myvar" | cut -c1
salidas \
como se esperaba.
Ver también: /programming/1405611/extracting-first-two-characters-of-a-string-shell-scripting
Probado en Ubuntu 19.04.
printf '%s' "$myvar" | cut -c2
no es POSIX ya que la salida de printf
no es texto a menos que $myvar
termine en un carácter de nueva línea. De lo contrario, se supone que la variable no contiene caracteres de nueva línea, ya que cut
corta cada línea de su entrada.
awk
uno sería más eficiente y confiable conawk -- 'BEGIN {print substr (ARGV[1], 2, 1)}' "$myvar"
cut
, eso no funciona para caracteres de varios bytes (lo mismo para mawk u busybox awk)
printf 'abc '| cut -c2
está mal porque no \n
(esto no lo sé) o que el comando fallará si myvar tiene líneas nuevas (estoy de acuerdo)?
cut
no se especifica si la entrada no es texto (aunque cut
se requieren implementaciones para manejar líneas o longitud arbitraria). La salida de printf abc
no es texto, ya que no termina en un carácter de nueva línea. En la práctica, dependiendo de la aplicación, si la tubería que a cut -c2
, se obtiene ya sea b
, b<newline>
o nada en absoluto. Necesitaría printf 'abc\n' | cut -c2
obtener un comportamiento especificado por POSIX (que se requiere para la salida b<newline>
)
Con zsh
o yash
, usarías:
$ text='€$*₭£'
$ printf '%s\n' "${text[3]}"
*
(en zsh
, puedes acortarlo a printf '%s\n' $text[3]
).
Puedes usar el comando de corte. Para obtener la tercera posición:
echo "SAMPLETEXT" | cut -c3
Consulte este enlace http://www.folkstalk.com/2012/02/cut-command-in-unix-linux-examples.html
( Casos avanzados ) Sin embargo, modificar IFS también es algo bueno, especialmente cuando su entrada puede tener espacios. Solo en ese caso, use el siguiente
saveifs=$IFS
IFS=$(echo -en "\n\b")
echo "SAMPLETEXT" | cut -c3
IFS=$saveifs
IFS
entraría en juego el código que publicaste.