Вопрос Как удалить многострочную запись из текстового файла?


Например, test.txt содержит:

Hi
Hello
Hi world

Код ниже удаляет слово из test.txt и создает файл temp test_removed.txt, который содержит:

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

Код ниже выполняет поиск вашего слова и распечатает его. Например, если вы выполните поиск «Привет», он распечатает «Hi Hi World» точно так же, как и все в одной строке.

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

В моем коде ниже я заметил, что в последней строке кода в блоке «a» кода, если вместо создания новой строки для каждой из 6 частей информации, заданной пользователю, она имела все это в 1 строке то код, указанный выше для удаления и поиска, сделает это правильно. Но поскольку есть несколько строк для удаления, я не уверен, что делать. Чтобы удалить, он просто запрашивает у пользователя имя и фамилию. Для поиска просто запрашивается имя.

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

2
2018-03-26 16:18


происхождения


Почему бы просто не разделить данные по ; внедрен \n? - c0rp
@ c0rp, который может стоить ответа. - terdon♦


ответы:


Формат вашего файла имеет две последовательные строки новой строки (\n\n) между каждой записью:

First Name: Elvis
Last Name: Presley
Phone Number: 123456
Address: 12 lonely street
Email: theking@graceland.com

First Name: BB
Last Name: King
Phone Number: 7891012
Address: 11 blues lane
Email: bbking@lucille.com

Вы можете использовать это, чтобы идентифицировать запись и удалить ее в своем скрипте. Например, эта команда perl удалит запись Элвиса из вышеуказанного файла:

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, это приведет к удалению записи Элвиса из файла.
  • 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

2
2018-03-26 16:55