Procura por um nome de usuário no arquivo e gera o número de telefone do usuário

4

Primeiro fiz um arquivo chamado telefone contendo:

Jan;032569874    
Annemie;014588529    
Hans;015253694    
Stefaan;011802367

E o que preciso fazer agora é criar um script no qual o usuário insira um nome e a saída seja semelhante,

The phone number of Jan is 032569874

Eu tentei muitas coisas, mas nada funcionou como deveria. Eu sei que é muito fácil, mas eu simplesmente não consigo entender.

Ok, essas respostas são claramente de um nível mais alto. Isso é o que eu consegui:

#!/bin/bash
#Solution script2

IFS=";"

echo "Whose phone number do you want to know?"
read name
read name number <$1
echo "The phone number of $name is $number."
    
por Sander Van der Borght 21.11.2014 / 23:44

6 respostas

6

Aqui está uma versão do seu script mais ou menos modificada:

$ more cmd.bash 
#!/bin/bash

echo "Whose phone number do you want to know?"
read name
number=$(grep "$name" telephone | cut -d';' -f2)
echo ''
echo "The phone number of $name is $number."

Funciona da seguinte forma:

$ ./cmd.bash 
Whose phone number do you want to know?
Hans

The phone number of Hans is 015253694.

Como funciona

Ele simplesmente recebe o nome por meio do comando read name e armazena o que foi digitado na variável $name . Em seguida, percorremos o arquivo telephone e usamos cut para dividir a linha resultante do arquivo telephone em 2 campos, usando o ponto-e-vírgula como caractere de separação. O número de telefone, arquivado 2, é armazenado na variável $number .

Teste

Você pode usar o seguinte script para testar se o script funciona, usando os dados do arquivo telephone .

$ while read -r i ;do 
    echo "-----"
    echo "Test \"$i\""
    ./cmd.bash <<<$i
    echo "-----"
  done < <(cut -d';' -f1 telephone)

Os comandos acima leem o conteúdo do arquivo telephone , dividem-no no ponto e vírgula, ; e, em seguida, obtêm cada valor do campo 1 (nomes) e fazem um loop por eles 1 por vez. Cada nome é então passado para o seu script, cmd.bash , via STDIN, aka. %código%. Isso simula um usuário digitando cada um dos nomes.

$ while read -r i ;do echo "-----"; echo "Test \"$i\""; \
    ./cmd.bash <<<$i; echo "-----"; done < <(cut -d';' -f1 telephone)
-----
Test "Jan"
Whose phone number do you want to know?

The phone number of Jan is 032569874.
-----
-----
Test "Annemie"
Whose phone number do you want to know?

The phone number of Annemie is 014588529.
-----
-----
Test "Hans"
Whose phone number do you want to know?

The phone number of Hans is 015253694.
-----
-----
Test "Stefaan"
Whose phone number do you want to know?

The phone number of Stefaan is 011802367.
-----
    
por 22.11.2014 / 02:31
6

Usando awk :

#!/usr/bin/awk -f
BEGIN { FS=";" } $1 ~ name { print "The number of " name " is " $2 }
phones -v name=Jan telephone                                      
The number of Jan is 032569874
    
por 22.11.2014 / 00:32
2
name="jan"
line="$(grep -i ^"$name" file)"
if [ -n "$line" ]; then
  number="${line#*;}"
  echo "The phone number of ${name} is ${number}"
else
  echo "There is no phone number for ${name}."
fi 
    
por 21.11.2014 / 23:51
1

Um simples marcador:

read name; grep $name telephone | awk -F ';' '{print "The phone number of "$1" is "$2}'

Exemplo de uso:

Jan
The phone number of Jan is 032569874
  • read lê a entrada em uma variável chamada name . A entrada é aceita após read receber uma nova linha ou retorno de carro (por exemplo, pressionando Enter).

  • grep pesquisa no arquivo telefônico a entrada armazenada em name , retornando uma única linha, assumindo que o nome ocorre apenas uma vez.

  • awk é solicitado a usar um ponto-e-vírgula (;) como o delimitador de campo por meio do parâmetro -F ';' . O ponto-e-vírgula está entre aspas para impedir que o shell o interprete.

  • O awk program {print "The phone number of "$1" is "$2} imprime o texto desejado ao substituir $1 e $2 pelos respectivos campos obtidos da linha canalizada de grep .

Você pode armazenar essa linha no seu arquivo .sh e executá-la como um script.

    
por 22.11.2014 / 07:59
1

Eu usei o comando grep com \k notify e lookbehind assertion :

$ read name; echo "The phone number of $name is $(grep -oP "$name;\K.*" telephone)"
  Jan                                  #Input
  The phone number of Jan is 032569874 #Output
O parâmetro

grep com -P (perl-regexp) suporta \K , que é usado para ignorar os caracteres previamente correspondidos (ignorar nome e ponto e vírgula;).

-o, --only-matching : imprime somente as partes correspondentes (não vazias) de uma linha correspondente.

$(command) "Substituição de Comando" que permite a saída de um comando para substituir o nome do comando.

Ou você pode usar a asserção lookbehind no lugar de nifty \K .

$ read name; echo "The phone number of $name is $(grep -oP "(?<=$name;).*" telephone)"
    
por 22.11.2014 / 07:40
1

com sed :

sed 's|.*|s/\(&\);\([0-9]*\).*/\1'\''s phone # is \2./p|;q' </dev/tty|
sed -nf - /dev/fd/3 3<<\IN
Jan;032569874 
Annemie;014588529 
Hans;015253694 
Stefaan;011802367
IN

O primeiro sed lê uma linha de entrada do terminal e a converte em uma instrução de substituição s/// para o segundo sed . Não há nada chique aqui - como ele vai quebrar se você der / na entrada, por exemplo, mas, basicamente, funciona:

OUTPUT

#I typed the line below then ENTER
Annemie
Annemie's phone # is 014588529.

Você provavelmente desejará fazer sed -nf - phonefilename em vez do /dev/fd/3 que usei para o nome do arquivo a ser demonstrado. E nesse caso você não precisará do bit <<IN...IN heredoc.

    
por 23.11.2014 / 21:36

Tags