Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

For example test.txt contains:

Hi
Hello
Hi world

The code below removes a word from test.txt and creates a temp file test_removed.txt which contains the:

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

The code below searches for your word and will print it out. For example, if you search "Hi", it will print out "Hi Hi World" exactly like that all in 1 line.

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

In my code below, I noticed that in the last line of code in the "a" block of code, if instead of making a new line for each of the 6 pieces of information asked of the user, it had it all in 1 line then the code above to remove and search will do it correctly. But since there are multiple lines to remove I'm not sure what to do. To remove, it just asks the user for first and last name. To search it just asks for first name.

#!/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"
share|improve this question
    
Why not just separate data by ; insted of \n? –  c0rp Mar 26 at 16:33
    
@c0rp that might be worth an answer. –  terdon Mar 26 at 17:01

1 Answer 1

up vote 2 down vote accepted

The format of your file has two consecutive newlines (\n\n) between each record:

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]

You can use this to identify a record and remove it in your script. For example, this perl command will remove Elvis's entry from the above file:

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

Explanation:

  • The -0 sets the input record separator. Setting this to 00 (with -000) activates 'paragraph mode' where Perl will use consecutive newlines (\n\n) as the record separator. In other words, a "line" is now defined

  • The -n means "read the input file line, by line and apply the script given with -e.

  • print unless /Elvis/ will print all lines that contain neither Elvis nor Presley. Since a "line" is now defined as a block of text separated by two newlines (\n\n) because of the -000, this will remove Elvis's entry from the file.
  • The i in the match operator (//i) makes the match case insensitive so that both Elvis and elvis will work. You can remove it if you don't want that.

Integrate into your script

To make this work with your script, we need another step. Perl has the special %ENV hash which holds the environmental variables currently defined. For example, $ENV{HOME} is your $HOME directory. To add a bash variable to this hash, you need to export it. So, what you can do is edit the b block of your script to export the variables and to use the perl script from above:

"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} will be $first and $ENV{last} will be $last.
  • The -i.bak means "edit the original file and create a backup copy called filename.bak". In other words, the perl command will delete the entry from contacts_firstname and create a backup of the original file called contacts_firstname.bak.

If you don't want a backup file, just use this instead:

perl -000 -i -ne 'print unless /$ENV{first}/i && /$ENV{last}/i' ./contacts_firstname
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.