.png)
Tengo el siguiente script que cuenta los caracteres en la entrada del usuario:
echo -n "Type text: ";
read mystring;
echo -n $mystring | wc -m;
Sin "-n" en la última línea, el recuento de caracteres sería incorrecto porque también incluiría el carácter de nueva línea colocado allí por echo (por lo que el recuento, por ejemplo, "abc" sería 4 en lugar de 3).
Para practicar, ahora quiero hacer esta corrección de una manera más complicada. La idea general es así:
var=$($mystring | wc -m);
echo -n "Type text: ";
read mystring;
echo $(( $var - 1 ));
Entonces, el recuento de caracteres de la entrada del usuario se convierte en $var y luego resto 1 de $var. ¿Cómo hago que funcione?
Respuesta1
Su script no funciona por varias razones:
- Comienza inicializando
var
para que sea igual al resultado de ejecutar el comando| wc -m
porquemystring
en este punto es nulo. - Incluso si no fuera nulo, intentaría ejecutar su contenido como un comando y enviar esa salida a
wc
.
Tienes que A> hacer las cosas en el orden correcto, y ii.> hacer las cosas correctas:
read -p "Type something > " mystring
var="$( wc -m <<< "$foo" )"
echo $(($var-1))
Respuesta2
Si desea contar la cantidad de caracteres que el usuario ingresó pero sin incluir el carácter de nueva línea, entonces debería ser:
#! /bin/sh -
printf 'Type text: '
IFS= read -r userInput
length=$(printf %s "$userInput" | wc -m)
# or:
length=${#userInput}
Si desea incluir el carácter de nueva línea que posiblemente ingresó el usuario, entonces:
#! /bin/sh -
printf 'Type text: '
IFS= read -r userInput && userInput="$userInput
"
length=$(printf %s "$userInput" | wc -m)
# or:
length=${#userInput}
read
normalmente regresaráverdaderosi se ingresó una línea completa (el carácter de nueva línea está presente), razón por la cual agregamos una si read
fue exitoso.
Tenga en cuenta que en la mayoría de las implementaciones de shell ( zsh
siendo la excepción), no funcionará correctamente si el usuario ingresa un ^@
carácter NUL (también conocido como ).
Para solucionar esto, podrías hacer:
printf 'Type text: '
length=$(line | wc -m)
en cambio. O:
length=$(line | tr -d '\n' | wc -m)
# or
length=$(($(line | wc -m) - 1)) # as line always includes a newline on
# output even if one was not provided on
# input.
si no quieres contar la nueva línea.
El comportamiento también variará si el usuario logra ingresar bytes que no forman parte de caracteres válidos. También encontrará algunas sh
implementaciones que ${#var}
no funcionan correctamente con caracteres de varios bytes (devolverían la longitud en bytes en lugar de caracteres).
Respuesta3
expr " $mystring" : '.*' - 1
devolverá la longitud del contenido de la variable de shellmystring
Respuesta4
En bash usarías
#!/usr/bin/env bash
read -p 'Type text: ' userInput
printf 'Your input was %d chars long\n' "${#userInput}"
El recuento de cadenas se puede recuperar mediante ${#var}
. wc
En este caso no es necesario utilizar