Bagaimana cara menghapus baris dari file teks yang mengandung kata-kata tertentu melalui terminal?


72

Bagaimana cara menghapus semua baris dari file teks yang mengandung kata "cat" dan "rat"?


Ini kedengarannya mencurigakan seperti tugas pekerjaan rumah. Harap ingat untuk menghubungkan jawaban Anda dengan orang-orang baik di Askubuntu.
zwets

Itu bagian dari proyek besar, saya baru mengenal lingkungan Linux.
PersonX

Jawaban:


100

grep pendekatan

Untuk membuat salinan file tanpa baris yang cocok dengan "cat" atau "rat", orang dapat menggunakan grepsecara terbalik ( -v) dan dengan opsi seluruh kata ( -w).

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

Opsi seluruh kata memastikan itu tidak akan cocok catsatau gratefulmisalnya. Redirection output dari shell Anda digunakan ( >) untuk menulisnya ke file baru. Kami membutuhkan -Eopsi untuk mengaktifkan ekspresi reguler yang diperluas untuk (one|other)sintaks.

sed pendekatan

Atau, untuk menghapus garis di tempat yang bisa digunakan sed -i:

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

The \bbatas set kata dan doperasi menghapus garis yang cocok dengan ekspresi antara garis miring ke depan. catdan ratkeduanya dicocokkan dengan (one|other)sintaks yang tampaknya perlu kita hindari dengan garis miring terbalik.

Tip: gunakan sedtanpa -ioperator untuk menguji output dari perintah sebelum menimpa file.

(Berdasarkan Sed - Hapus baris yang berisi string tertentu )


Saya ingin tahu apakah ada cara untuk mencapai penghapusan dari file sumber DAN menghasilkan file dengan cocok. Mungkin tidak, tetapi itu akan berguna (misalnya ketika Anda mendapatkan file yang tumbuh terlalu besar, Anda membaginya berdasarkan konten).
Sridhar Sarnobat

1
@ Sridhar-Sarnobat Oh, Anda bisa. Gunakan tee dan subkulit untuk menyalin stdout. Dalam satu Anda menyaring, yang lain kebalikannya. Penggunaan tee dan subkulit yang ditunjukkan dalam penggunaan yang tidak terkait ditunjukkan di sini: blog.g3rt.nl/…
gertvdijk

15

Untuk menguji di terminal saja, gunakan:

sed '/[cr]at/d' file_name

Untuk benar-benar menghapus garis-garis itu dari file, gunakan:

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

5

Coba dengan vim-way:

ex +"g/[cr]at/d" -scwq file.txt

0

Pertimbangkan jika Anda memiliki file dengan file_namedan Anda ingin mencari mouse tetapi pada saat yang sama beberapa baris dari mouse memiliki kata-kata lain seperti catdan ratdan Anda tidak ingin melihat orang-orang di output Anda, jadi satu-satunya cara untuk melakukannya adalah -

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

0

cara shell portabel

Bekerja di /bin/sh, yang ada dashdi Ubuntu, serta ksh, dan bash. Sedikit canggung bahwa Anda harus menulis beberapa test case untuk setiap kata dalam casepernyataan tetapi portabel. Bekerja dengan kasus di mana kata muncul sendiri di telepon, di awal, di akhir baris, atau di tengah kalimat, dan mengabaikan di mana kata itu mungkin menjadi bagian dari kata lain.

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

Dan ini cara kerjanya:

$ 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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.