.png)
Eu tenho o seguinte script que conta caracteres na entrada do usuário:
echo -n "Type text: ";
read mystring;
echo -n $mystring | wc -m;
Sem o "-n" na última linha, a contagem de caracteres estaria errada porque também incluiria o caractere de nova linha colocado lá por echo (portanto, a contagem para, por exemplo, "abc" seria 4 em vez de 3.)
Por uma questão de prática, quero agora fazer esta correção de uma forma mais complicada. A ideia geral é assim:
var=$($mystring | wc -m);
echo -n "Type text: ";
read mystring;
echo $(( $var - 1 ));
Portanto, a contagem de caracteres da entrada do usuário torna-se $var e subtraio 1 de $var. Como faço para que isso funcione?
Responder1
Seu script não funciona por vários motivos:
- Você começa inicializando
var
para ser igual à saída da execução do comando| wc -m
porquemystring
neste ponto é nulo. - Mesmo que não fosse nulo, ele tentaria executar seu conteúdo como um comando e enviaria essa saída para
wc
.
Você tem que A> fazer as coisas na ordem certa e ii.> fazer as coisas corretas:
read -p "Type something > " mystring
var="$( wc -m <<< "$foo" )"
echo $(($var-1))
Responder2
Se você quiser contar o número de caracteres que o usuário digitou, mas sem incluir o caractere de nova linha, então deve ser:
#! /bin/sh -
printf 'Type text: '
IFS= read -r userInput
length=$(printf %s "$userInput" | wc -m)
# or:
length=${#userInput}
Se você quiser incluir o caractere de nova linha que o usuário possivelmente inseriu, então:
#! /bin/sh -
printf 'Type text: '
IFS= read -r userInput && userInput="$userInput
"
length=$(printf %s "$userInput" | wc -m)
# or:
length=${#userInput}
read
normalmente retornaráverdadeirose uma linha completa foi inserida (o caractere de nova linha está presente), é por isso que acrescentamos um se read
foi bem-sucedido.
Observe que na maioria das implementações de shell ( zsh
sendo a exceção), ele não funcionará corretamente se o usuário inserir um ^@
caractere NUL (também conhecido como ).
Para contornar isso, você poderia fazer:
printf 'Type text: '
length=$(line | wc -m)
em vez de. Ou:
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.
se você não quiser contar a nova linha.
O comportamento também variará se o usuário conseguir inserir bytes que não façam parte de caracteres válidos. Você também encontrará algumas sh
implementações que ${#var}
não funcionam corretamente com caracteres multibyte (retornariam o comprimento em bytes em vez de caracteres).
Responder3
expr " $mystring" : '.*' - 1
retornará o comprimento do conteúdo da variável shellmystring
Responder4
No bash você usaria
#!/usr/bin/env bash
read -p 'Type text: ' userInput
printf 'Your input was %d chars long\n' "${#userInput}"
A contagem de strings pode ser recuperada por ${#var}
. Usar wc
é neste caso desnecessário