Como posso excluir um registro de várias linhas de um arquivo de texto?

2

Por exemplo, o test.txt contém:

Hi
Hello
Hi world

O código abaixo remove uma palavra do test.txt e cria um arquivo temp test_removed.txt que contém o:

#!/bin/bash
echo -n Enter Input: 
read input
sed -e "/^${input}/d" test.txt > test_removed.txt

O código abaixo pesquisa sua palavra e a imprime. Por exemplo, se você pesquisar "Hi", ele imprimirá "Hi Hi World" exatamente assim em uma linha.

#!/bin/bash
echo -n "Enter Input: "
read input
echo 'grep $input test.txt |awk -F":" {print $0}''

No meu código abaixo, notei que na última linha de código no bloco "a" de código, se em vez de criar uma nova linha para cada uma das 6 informações solicitadas ao usuário, ele tinha tudo em 1 linha, o código acima para remover e pesquisar fará isso corretamente. Mas desde há várias linhas para remover eu não tenho certeza do que fazer. Para remover, basta perguntar ao usuário pelo nome e sobrenome. Para pesquisá-lo, basta perguntar pelo primeiro nome.

#!/bin/bash

ok=0;

while ((ok==0))
    do
    echo "Main Menu:"
    echo -e "\t(a) Add"
    echo -e "\t(b) Remove"
    echo -e "\t(c) Seach"
    echo -e "\t(d) Display contacts"
    echo -e "\t(e) Exit"
    echo -n "Please enter your choice:"
    read choice
    case $choice in
           "a"|"A")
            ok=1
            echo -e "[Add c ontact]"
            echo -n "First N ame: "
            read firstName
            echo -n "Last N ame: "
            read lastName
            echo -n "Phone Number: "
            read phoneNumber
            echo -n "Address: "
            read address
            echo -n "Email: "
            read email
            echo "$firstName $lastName is added to your contacts"
            echo -e "First Name: $firstName\nLast Name: $lastName\nPhone Number: $phoneNumber\nAddress: $address\nEmail: $email\n\n" >> ./contacts_firstname
            ;;
            "b"|"B")
            ok=1
            echo -e "[Remove a c ontact]"
            echo -n "First N ame: "
            read first
            echo -n "Last N ame: "
            read last
            sed -e "/^${first}/d" contacts_firstname > contacts

            ;;
            "c"|"C")
            ok=1
            echo -e "[Search c ontacts]"
            echo -n "Search by the contact's First N ame: "
            read FName
            echo 'grep $FName contacts_firstname | awk -F":" '{print $0}''
            ;;
            "d"|"D")
            ok=1

            ;;
            "e"|"E")
            exit
            ;;
            *)
            echo "invalid answer, please try again"
            ;;



    esac
done

echo "You entered $choice"
    
por Selena Gomez 26.03.2014 / 17:18

1 resposta

2

O formato do seu arquivo tem duas novas linhas consecutivas ( \n\n ) entre cada registro:

First Name: Elvis
Last Name: Presley
Phone Number: 123456
Address: 12 lonely street
Email: [email protected]

First Name: BB
Last Name: King
Phone Number: 7891012
Address: 11 blues lane
Email: [email protected]

Você pode usar isso para identificar um registro e removê-lo em seu script. Por exemplo, este comando perl irá remover a entrada de Elvis do arquivo acima:

perl -000 -ne 'print unless /Elvis/ && /Presley/' test.txt 

Explicação:

  • O -0 define o separador de registro de entrada. Definir isso como 00 (com -000 ) ativa o 'modo de parágrafo', onde o Perl usará novas linhas consecutivas ( \n\n ) como separador de registro. Em outras palavras, uma "linha" agora é definida

  • O -n significa "leia a linha do arquivo de entrada, por linha e aplique o script fornecido com -e .

  • print unless /Elvis/ imprime todas as linhas que contêm nenhuma Elvis nem Presley . Como uma "linha" agora é definida como um bloco de texto separado por duas novas linhas (\n\n) devido ao -000 , isso removerá a entrada de Elvis do arquivo.
  • O i no operador de correspondência ( //i ) torna a correspondência insensível ao caso, de forma que Elvis e elvis funcionem. Você pode removê-lo se não quiser isso.

Integre seu script

Para que isso funcione com o seu script, precisamos de mais um passo. O Perl tem o %ENV hash especial que contém as variáveis ambientais definidas atualmente. Por exemplo, $ENV{HOME} é seu diretório $HOME . Para adicionar uma variável bash a este hash, você precisa export it. Então, o que você pode fazer é editar o bloco b do seu script para exportar as variáveis e usar o script perl acima:

"b"|"B")
ok=1
echo -e "[Remove a contact]"
echo -n "First Name: "
read first
echo -n "Last Name: "
read last

## export the variables, to make them available to the 'perl' script
export first
export last
## remove the entry from the file and create a backup
perl -000 -i.bak -ne 'print unless /$ENV{first}/i && /$ENV{last}/i' ./contacts_firstname
  • $ENV{first} será $first e $ENV{last} será $last .
  • O -i.bak significa "edite o arquivo original e crie uma cópia de backup denominada filename.bak". Em outras palavras, o comando perl excluirá a entrada de contacts_firstname e criará um backup do arquivo original chamado contacts_firstname.bak .

Se você não quiser um arquivo de backup, use-o:

perl -000 -i -ne 'print unless /$ENV{first}/i && /$ENV{last}/i' ./contacts_firstname
    
por terdon 26.03.2014 / 17:55