Exercício na contagem de caracteres (bash)

1

Eu tenho o seguinte script que conta os 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 posto lá por echo (então a contagem de, por exemplo, "abc" seria 4 em vez de 3). / p>

Por uma questão de prática, agora quero fazer essa correção de uma maneira 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 se torna $ var e, em seguida, subtraio 1 de $ var. Como faço para que funcione?

    
por wsurfer0 24.04.2017 / 21:42

4 respostas

2

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 porque mystring está neste ponto nulo.
  • Mesmo que não fosse nulo, ele tentaria executar seu conteúdo como um comando e enviar essa saída para wc .

Você tem que A > fazer as coisas na ordem certa, e ii. > faça as coisas corretas:

read -p "Type something > " mystring
var="$( wc -m <<< "$foo" )"
echo $(($var-1))
    
por 24.04.2017 / 21:48
2

Se você quiser contar o número de caracteres em que o usuário inseriu, mas não incluindo o caractere de nova linha, deverá estar:

#! /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á verdadeiro se uma linha completa foi inserida (o caractere de nova linha está presente) e é por isso que adicionamos um se read for bem-sucedido.

Observe que na maioria das implementações do 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 disso. 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 fazem parte de caracteres válidos. Você também encontrará algumas sh implementações cujo ${#var} não funciona corretamente com caracteres de múltiplos bytes (retornaria o comprimento em bytes em vez de caracteres).

    
por 24.04.2017 / 22:14
1
expr " $mystring" : '.*' - 1

retornará o comprimento do conteúdo da variável do shell mystring

    
por 25.04.2017 / 07:16
0

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

    
por 24.04.2017 / 21:51