Wie man Linien entlang eines bestimmten Musters grepst?

8

Nehmen wir an, ich habe eine Datei mit folgenden zwei Zeilen:

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

Ich brauche nur die Zeile mit dem Muster /aa/bbbb/cccccc , die zweite Zeile muss keine zusätzlichen Zeichen enthalten, also ?dddddddd . Jetzt, als ich es versuchte

grep '/aa/bbbb/cccccc' file

Dann werden beide Linien ausgewählt. Ich brauche die vollständige Zeile, damit grep -o keine Lösung sein kann.

Was könnte die mögliche Lösung mit grep sein, so dass nur die erste Zeile basierend auf dem Suchmuster ausgewählt wird?

    
heemayl 16.11.2014, 12:55

3 Antworten

7

Probieren Sie den folgenden Befehl grep aus, der den Parameter -P ( Perl-regexp ) verwendet.

grep -P '(?<!\S)/aa/bbbb/cccccc(?!\S)' file
  • (?<!\S) Dieser negative Lookbehind bestätigt, dass das Zeichen, das vor der Zeichenfolge /aa/bbbb/cccccc steht, ein beliebiges Zeichen außer Leerzeichen ist.

  • (?!\S) Negatives Lookahead bestätigt, dass das Zeichen, das auf die Übereinstimmung folgt, ein beliebiges Nicht-Leerzeichen ist.

Ein anderer Grep,

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

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

Speichern Sie den obigen Code in einer Datei und benennen Sie ihn als script.py . Führen Sie das obige Skript dann mit

aus
python3 script.py /path/to/the/file/you/want/to/work/with
    
Avinash Raj 16.11.2014, 12:58
10

Der einfachste Weg wäre, nach dem Muster ein Leerzeichen einzufügen:

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

Oder um alle Arten von Whitespaces zu finden:

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

Oder

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

Oder mit einem positiven Lookahead :

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

Oder mit einem negativen Lookahead :

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

Oder Sie können das Spiel umkehren:

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

Oder, um auch Zeilen zu finden, die nichts als Ihr Muster enthalten (keine nachgestellten Leerzeichen):

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

Oder Sie können einfach ein kleines Skript verwenden:

  • In awk:

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

    Oder wenn Sie nicht wissen, in welchem ​​Feld Ihr Muster ist

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

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

Zur Ergänzung @AvinashRaj s Antwort , Sie können auch einen solchen Befehl verwenden.

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

Tags und Links