Bagaimana menemukan garis yang cocok dengan suatu pola dan menghapusnya?


14

Dalam file dengan banyak baris saya ingin menghapus baris yang dimulai dengan HERE IT IS.

Bagaimana saya bisa melakukan ini hanya dengan menggunakan alat baris perintah?


2
Meskipun sedikit tidak konvensional, Anda dapat menggunakan vimseperti vim '+g/^HERE IT IS/d' +wq test.txt
:;

@ Doorknob, terima kasih telah menunjukkan ini. Sebenarnya saya sedang dalam perjalanan untuk menggunakan vim
micgeronimo

Jawaban:


28

Coba sed:

sed -i '/^HERE IT IS/d' <file>

PERINGATAN: Lebih baik mengambil cadangan saat menggunakan -isakelar sed:

sed -i.bak '/^HERE IT IS/d' <file>

File asli akan tetap <file>.bakdan file yang diubah akan <file>.


Bagaimana saya bisa menempatkan karakter baris baru setelah string yang cocok dan menulis ke baris baru?
micgeronimo

2
sed -i 's/^HERE IT IS/HERE IT IS\n/' <file>
heemayl

1
@ micgeronimo: senang membantu. Tolong periksa suntingan saya.
heemayl

6
@ micgeronimo mencoba untuk mengajukan pertanyaan yang Anda benar-benar ingin dijawab dalam pertanyaan awal Anda (ingat Anda dapat mengeditnya), daripada melalui komentar yang mungkin dibersihkan / dihapus. Anda bisa menggunakannya sed '/^HERE IT IS/G' file.
steeldriver

1
Penggunaan sed sangat pro.
LakshyaAg

18

Selain jawaban yang sangat bagus grepdan yang sedAnda terima, berikut adalah beberapa alat lain yang dapat melakukan hal yang sama:

  • Beberapa cara Perl:

    perl -ne '/^HERE IT IS/ || print' file > newfile
    perl -ne 'print if !/^HERE IT IS/' file > newfile
    perl -ne 'print unless /^HERE IT IS/' file > newfile
    

    Anda dapat menambahkan -iperalihan ke salah satu contoh untuk mengedit file di tempat:

    perl -i.bak -ne '/^HERE IT IS/ || print' file        
    
  • (melongo

    awk '!/^HERE IT IS/' file > newfile
    

    Versi yang lebih baru (4.1.1 dan yang lebih baru) dari GNU awk(default awkpada Linux) juga dapat mengedit file di tempat:

    gawk -i inplace  '!/^HERE IT IS/' file
    
  • Shell ( bash, zsh, ksh, mungkin orang lain). Ini agak konyol, itu bisa dilakukan tetapi alat lain lebih baik.

    while IFS= read -r line; do 
      [[ $line =~ ^"HERE IT IS" ]] || printf "%s\n" "$line"
    done < file > newfile
    

1
Anda hanya pamer! ;-) (tapi Anda mendapat suara positif, karena pintar dan saya belajar banyak dan yang bashmembuat saya LOL)
Fabby

bash yang harus digunakan printf "%s\n" "$line": mengutip $ line untuk mempertahankan spasi putih, dan menghindari beberapa masalah gema (menafsirkan karakter khusus, dll). dan menghindari kebutuhan untuk menambahkan --juga.
Olivier Dulac

@OlivierDulac cukup adil. Saya tidak ingin menyulitkan hal-hal untuk kasus pinggiran tetapi karena Cuanglm telah menambahkan IFS=dan -r, saya mungkin juga berusaha keras dan membuatnya kuat.
terdon

@terdon: semuanya baik-baik saja ^^ (dan saya sudah memberi +1, karena ini sangat informatif untuk pemula)
Olivier Dulac

2
@OlivierDulac Saya dapat meyakinkan Anda bahwa jika saya memposting di Unix & Linux saya akan menggunakan printf, IFS =, -r dan mengutip :). Saya sering menyederhanakan hal-hal untuk audiens AU yang sering kurang nyaman dengan baris perintah.
terdon

13

Saya akan gunakan grepuntuk memfilternya. Sebagai contoh :

grep -v "^HERE IT IS" infile > outfile

Kemudian pindahkan file outfile kembali ke infile.


Pemikiran cerdas
Anwar

5

sed jelas merupakan cara untuk pergi.

Ini sedikit modifikasi dari perintah @heemayl memberi Anda akan menghapus baris apakah kasus yang sama digunakan dalam pola atau tidak, karena I dalam referensi pola.

sed -i '/HERE IT IS/Id' <file>

Jika Anda memiliki beberapa file dalam direktori yang Anda inginkan, Anda dapat menggabungkannya dengan find seperti itu.

find . -maxdepth 1 -type f -exec sed -i.bak '/HERE IT IS/Id' {} +

Opsi maxdepth berarti ini tidak akan muncul kembali ke direktori.


4

Opsi python lain:

#!/usr/bin/env python3
[print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]

Di mana f adalah path ke file, di antara tanda kutip.


4

Grep

grep -P '^(?!HERE IT IS)' file

(?!HERE IT IS)pernyataan lookahead negatif yang membuat mesin regex untuk mencocokkan semua garis batas mulai ( yang biasanya cocok dengan^ ) hanya jika tidak diikuti oleh stringHERE IT IS

ular sanca

#!/usr/bin/python3
import sys
fil = sys.argv[1]
with open(fil) as f:
    for line in f:
        if not line.startswith('HERE IT IS'):
            print(line, end="")

Simpan skrip dalam file, ucapkan script.pydan kemudian jalankan melalui perintah di bawah ini di terminal.

python3 script.py infile

Anda bisa menggunakan regex di sana, seperti [print(l, end = "") for l in open(fil).readlines() if not re.match("HERE IT IS", l)], tapi itu tidak jauh lebih efisien daripada startswith. Saya bertanya-tanya bagaimana [print(l, end = "") for l in open(f).readlines() if not l.startswith("HERE IT IS")]tidak akan menghasilkan output dalam daftar.
Avinash Raj

Pertama kali saya menabraknya, itu tampak aneh bagi saya. Ini menghasilkan perintah cetak (atau tindakan apa pun yang ingin Anda lakukan dengannya) untuk semua item dalam daftar yang ditentukan.
Jacob Vlijm

Membatalkan penghapusan, hanya untuk bersenang-senang :)
Jacob Vlijm

1

Anda dapat menggunakan Vim dalam mode Ex:

ex -sc 'g/^HERE IT IS/d' -cx file
  1. g pencarian global

  2. d menghapus

  3. x Simpan dan tutup

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.