如何从文本文件中删除多行记录?

如何从文本文件中删除多行记录?

例如 test.txt 包含:

Hi
Hello
Hi world

下面的代码从 test.txt 中删除一个单词并创建一个临时文件 test_removed.txt,其中包含:

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

以下代码会搜索您要搜索的单词并将其打印出来。例如,如果您搜索“Hi”,它会在一行中打印出完全相同的“Hi Hi World”。

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

在下面的代码中,我注意到在“a”代码块的最后一行代码中,如果不是为用户询问的 6 条信息中的每一条都创建一个新行,而是将所有内容放在一行中,那么上面的删除和搜索代码就可以正确完成。但由于有多行需要删除,我不确定该怎么做。要删除,它只会要求用户输入名字和姓氏。要搜索,它只会要求输入名字。

#!/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"

答案1

您的文件格式\n\n在每个记录之间有两个连续的换行符 ( ):

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]

您可以使用它来识别记录并在脚本中将其删除。例如,此 perl 命令将从上述文件中删除 Elvis 的条目:

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

解释:

  • 设置-0输入记录分隔符。将其设置为00(使用-000)可激活“段落模式”,其中 Perl 将使用连续换行符(\n\n)作为记录分隔符。换句话说,现在定义了一个“行”

  • 意思-n是“逐行读取输入文件并应用给定的脚本-e

  • print unless /Elvis/将打印包含以下内容的所有行两者都不 Elvis 也不 Presley由于现在将“行”定义为由两个换行符分隔的文本块,(\n\n)因此-000这将从文件中删除 Elvis 的条目。
  • 匹配i运算符 ( //i) 使匹配不区分大小写,因此和 都Elvis可以elvis正常工作。如果您不想要它,可以将其删除。

集成到你的脚本中

为了使这个在你的脚本中工作,我们还需要另一个步骤。Perl 有特殊的%ENV哈希它保存当前定义的环境变量。例如,$ENV{HOME}是您的$HOME目录。要将 bash 变量添加到此哈希,您需要export它。因此,您可以做的是编辑b脚本的块以导出变量并使用上面的 perl 脚本:

"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}将会$first并且$ENV{last}将会$last
  • 意思-i.bak是“编辑原始文件并创建一个名为 filename.bak 的备份”。换句话说,perl 命令将从中删除条目contacts_firstname并创建原始文件的备份,名为contacts_firstname.bak

如果您不想要备份文件,请使用这个:

perl -000 -i -ne 'print unless /$ENV{first}/i && /$ENV{last}/i' ./contacts_firstname

相关内容