Bagaimana cara mengambil garis, berdasarkan pola tertentu?

8

Katakanlah saya memiliki file yang berisi dua baris berikut:

2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
2014-05-05      09:12:17    /aa/bbbb/cccccc?dddddddd    16767 

Saya perlu mendapatkan baris yang berisi pola /aa/bbbb/ccccccsaja, saya tidak perlu baris kedua yang mengandung karakter tambahan yaitu ?dddddddd. Sekarang ketika saya mencoba

grep '/aa/bbbb/cccccc' file

Kemudian kedua garis dipilih. Saya perlu garis penuh sehingga grep -otidak bisa menjadi solusi.

Apa yang bisa menjadi solusi yang mungkin menggunakan grep sehingga hanya baris pertama yang dipilih berdasarkan pola pencarian?

heemayl
sumber

Jawaban:

7

Coba perintah grep di bawah ini yang menggunakan parameter -P( Perl-regexp ).

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S)Tampilan negatif di belakang ini menegaskan bahwa karakter yang mendahului string /aa/bbbb/ccccccadalah karakter non-spasi.

  • (?!\S) Lookahead negatif menegaskan bahwa karakter yang mengikuti pertandingan adalah karakter non-spasi.

Grep lain,

 grep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file

Melalui python,

script.py

#!/usr/bin/python3
import re
import sys
file = sys.argv[1]
with open(file, 'r') as f:
    for line in f:
        for i in line.split():
            if i == "/aa/bbbb/cccccc":
                print(line, end='')

Simpan kode di atas dalam file dan beri nama script.py. Kemudian jalankan skrip di atas dengan

python3 script.py /path/to/the/file/you/want/to/work/with
Avinash Raj
sumber
Terima kasih sobat. Btw dapatkah ini dilakukan dengan menggunakan regex normal / diperpanjang daripada perl regex?
heemayl
1
seperti terdon yang diposting, Anda bisa sajagrep '/aa/bbbb/cccccc ' file
Avinash Raj
Tetapi di atas tidak akan mencetak garis yang hanya memiliki /aa/bbbb/ccccccstring.
Avinash Raj
Anda dapat mencocokkannya juga dengangrep -E '/aa/bbbb/cccccc(\s+|$)' file
terdon
ya, seperti inigrep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Avinash Raj
10

Cara paling sederhana adalah menambahkan spasi setelah pola Anda:

$ grep '/aa/bbbb/cccccc ' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Atau, untuk mencocokkan semua jenis spasi putih:

$ grep  '/aa/bbbb/cccccc[[:space:]]' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Atau

$ grep -P '/aa/bbbb/cccccc\s+' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Atau, dengan tampilan positif :

$ grep -P '/aa/bbbb/cccccc(?=\s)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Atau, dengan tampilan negatif :

$ grep -P '/aa/bbbb/cccccc(?!\S)' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Atau Anda dapat membalikkan pertandingan:

$ grep  -v 'c?' file
2014-05-05      09:11:53    /aa/bbbb/cccccc             29899

Atau, untuk juga mencocokkan garis yang tidak mengandung apa pun kecuali pola Anda (tanpa spasi spasi tambahan):

grep -P '/aa/bbbb/cccccc(\s+|$)' file 
grep -E '/aa/bbbb/cccccc(\s+|$)' file 

Atau, Anda bisa menggunakan skrip kecil:

  • Dalam awk:

    $ awk '$3=="/aa/bbbb/cccccc"' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

    Atau, jika Anda tidak tahu di bidang mana pola Anda berada

    $ awk '{for(i=1;i<=NF;i++){if($i=="/aa/bbbb/cccccc"){print}}}' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    
  • Dalam Perl

    $ perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    
terdon
sumber
@terdon grep -v 'c?' filemengapa Anda tidak menggunakan grep -v '?' filekarena file hanya memiliki dua baris di dalamnya.
αғsнιη
@ KasiyA benar, saya hanya ingin mempertahankan sedikit polanya. Anda cukup benar, dalam kasus khusus ini, grep -v '?'sudah cukup.
terdon
2

Untuk melengkapi @AvinashRaj 's jawaban , Anda juga dapat menggunakan perintah seperti ini.

grep -P '/a+/b+/c+(?!\S)' file
αғsнιη
sumber