![如何从文本文件中删除多行记录?](https://linux22.com/image/851436/%E5%A6%82%E4%BD%95%E4%BB%8E%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E4%B8%AD%E5%88%A0%E9%99%A4%E5%A4%9A%E8%A1%8C%E8%AE%B0%E5%BD%95%EF%BC%9F.png)
例如 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