Как к grep строкам, на основе определенного шаблона?

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

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 так, чтобы только первая строка была выбрана на основе шаблона поиска?

8
задан 16 November 2014 в 15:40

3 ответа

Попробуйте ниже команды grep, которая использует -P (Perl-regexp) параметр.

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S) Этот отрицательный lookbehind утверждает, что символ, который предшествует строке /aa/bbbb/cccccc был бы любой, но не непробел.

  • (?!\S) Отрицательное предвидение утверждает, что символ после соответствия был бы любым, но не непробелом.

Другой grep,

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

Через 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='')

Сохраните вышеупомянутый код в файле и назовите его как script.py. Затем выполните вышеупомянутый сценарий

python3 script.py /path/to/the/file/you/want/to/work/with
7
ответ дан 16 November 2019 в 16:46

Чтобы дополнить ответ @AvinashRaj , вы также можете использовать такую ​​команду.

grep -P '/a+/b+/c+(?!\S)' file
2
ответ дан 16 November 2019 в 16:46

Самый простой путь состоял бы в том, чтобы добавить пространство после Вашего шаблона:

$ 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:

    $ 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
    
10
ответ дан 23 November 2019 в 05:24

Другие вопросы по тегам:

Похожие вопросы: