Як підкреслити лінії, спираючись на певний візерунок?


8

Скажімо, у мене є файл, що містить два рядки:

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

Мені потрібно отримати рядок, що містить лише шаблон /aa/bbbb/cccccc, мені не потрібен другий рядок, який містить додаткові символи, тобто ?dddddddd. Тепер, коли я спробував

grep '/aa/bbbb/cccccc' file

Потім обидва рядки вибираються. Мені потрібен повний рядок, щоб grep -oне могло бути рішення.

Що може бути можливим рішенням із використанням grep, щоб лише перший рядок був обраний на основі шаблону пошуку?

Відповіді:


7

Спробуйте нижче команду grep, яка використовує параметр -P( Perl-regexp ).

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S)Цей негативний погляд ззаду стверджує, що символ, який передує рядку /aa/bbbb/cccccc, буде будь-яким, але не непробільним символом.

  • (?!\S) Негативний підказник стверджує, що персонаж, який слідкує за збігом, буде будь-яким, але не непробільним символом.

Ще один греп,

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

Через пітон,

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='')

Збережіть вищезазначений код у файлі та назви його як script.py. Потім виконайте вищезгаданий сценарій

python3 script.py /path/to/the/file/you/want/to/work/with

Спасибі людина. Btw це можна зробити, використовуючи звичайний / розширений регулярний вираз, а не пергельгекс?
heemayl

1
як Terdon розміщено, ви можете простоgrep '/aa/bbbb/cccccc ' file
Avinash Raj

Але вище не буде надруковано рядки, у яких є лише /aa/bbbb/ccccccрядок.
Авінаш Радж

Ви також можете grep -E '/aa/bbbb/cccccc(\s+|$)' file
погодитись

так, ось такgrep -E '(^|\s)/aa/bbbb/cccccc(\s|$)' file
Avinash Raj

10

Найпростішим способом було б додати пробіл після вашого шаблону:

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

Або, щоб відповідати всім пробілам:

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

Або

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

Або, з позитивною підказкою :

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

Або з негативною підказкою :

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

Або ви можете скасувати відповідність:

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

Або також відповідати рядкам, що не містять нічого, окрім вашого шаблону (без пробілів):

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

Або ви можете просто скористатися невеликим сценарієм:

  • У див:

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

    Або якщо ви не знаєте, в якому полі знаходиться ваш шаблон

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

    $ perl -ane 'print if grep {$_ eq "/aa/bbbb/cccccc"} @F' file
    2014-05-05      09:11:53    /aa/bbbb/cccccc             29899
    

@terdon, grep -v 'c?' fileчому ви не використовуєте, grep -v '?' fileтому що файл містить лише два рядки.
αғsnιη

@KasiyA правда, я просто хотів трохи зберегти схему. Ви абсолютно праві, хоча і в цьому конкретному випадку grep -v '?'вистачило б.
тердон

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.