Як видалити рядки з текстового файлу, що містить конкретні слова через термінал?


72

Як видалити всі рядки з текстового файлу, що містять слова "кішка" та "щур"?


Це звучить підозріло, як домашнє завдання. Будь ласка, не забудьте приписувати свою відповідь приємним людям на Аскубунту.
zwets

Що є частиною великого проекту, я новачок у середовищі Linux.
PersonX

Відповіді:


100

grep підхід

Щоб створити копію файлу без рядків, що відповідають "cat" або "rat", можна скористатися grepв зворотному ( -v) і з цілим словом ( -w).

grep -vwE "(cat|rat)" sourcefile > destinationfile

Опція цілого слова робить , що він не буде відповідати catsабо gratefulнаприклад. Перенаправлення виводу вашої оболонки використовується ( >) для запису її до нового файлу. Нам потрібна -Eопція для включення розширених регулярних виразів для (one|other)синтаксису.

sed підхід

Крім того, для видалення рядків на місці можна скористатися sed -i:

sed -i "/\b\(cat\|rat\)\b/d" filename

Ці \bкордони безлічі слів і dоперація видаляють рядок , відповідний вираз між косою рисою. catі ratобидва вони узгоджуються з (one|other)синтаксисом, який нам, мабуть, потрібен, щоб уникнути зворотних нахилів.

Порада: використовуйте sedбез -iоператора тестування результатів команди перед тим, як перезаписати файл.

(На основі Sed - видалення рядка, що містить певний рядок )


Цікаво, чи є спосіб досягти як видалення з вихідного файлу, так і генерувати файл зі збігами. Напевно, ні, але це було б корисно (наприклад, коли ви отримуєте занадто великий файл, ви ділите його на основі вмісту).
Шрідхар Сарнобат

1
@ Шрідхар-Сарнобат О, ти можеш. Використовуйте трійник і підрозділи, щоб скопіювати stdout. В одному ви фільтруєте, в іншому зворотно. Використання трійника та піддонів, продемонстрованих у спорідненому
gertvdijk

15

Для тестування лише в терміналі використовуйте:

sed '/[cr]at/d' file_name

Щоб дійсно видалити ці рядки з файлу, використовуйте:

sed -i '/[cr]at/d' file_name


0

Подумайте, чи є у вас файл, file_nameі ви хочете шукати мишу, але в той же час кілька рядків у миші, які мають інші слова, такі як catі, ratі ви не хочете бачити їх у своєму висновку, тож один із способів зробити це -

grep -r mouse file_name | grep -vE "(cat|rat)"

0

портативний оболонки спосіб

Працює в /bin/sh, що знаходиться dashна Ubuntu, а також ksh, і bash. Трохи незручно, що вам потрібно написати кілька тестових випадків для кожного слова у caseвисловлюванні, але переносно. Працює з випадками, коли слово з’являється поодинці на рядку, на початку, в кінці рядка або середині рядка, і ігнорує, де воно може бути частиною іншого слова.

#!/bin/sh
line_handler(){
   # $1 is line read, prints to stdout
    case "$1" in
        cat|cat\ *|*\ cat\ *|*\ cat) true;; # do nothing if cat or rat in line
        rat|rat\ *|*\ rat\ *|*\ rat) true;; 
        *) printf "%s\n" "$1"
    esac
}

readlines(){
    # $1 is input file, the rest is words we want to remove
    inputfile="$1"
    shift

    while IFS= read -r line;
    do
        line_handler "$line" "$@"
    done < "$inputfile"
    [ -n "$line" ] && line_handler "$line" 
}

readlines "$@"

Ось як це працює:

$ cat input.txt                                                                                                                                                        
the big big fat cat
the cat who likes milk 
jumped over gray rat
concat 
this is catchy
rat
rational
irrational
$ ./dellines.sh input.txt                                                                                                                                              
concat 
this is catchy
rational
irrational
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.