it-swarm.com.de

Kann grep nur Wörter anzeigen, die dem Suchmuster entsprechen?

Gibt es eine Möglichkeit, dass grep "Wörter" aus Dateien erzeugt, die dem Suchausdruck entsprechen?

Wenn ich alle Fälle von "th" in einer Reihe von Dateien finden möchte, kann ich Folgendes tun:

grep "th" *

aber die Ausgabe wird etwas sein (fett ist von mir);

 einige-text-datei: das  Katze setzte sich auf das  mat 
 some-other-text-file: das  quick brown fox 
 noch eine andere-text-datei: ich hoffe diese  erklärt es gründlich

Was ich mit derselben Suche ausgeben möchte, ist:

the
the
the
this
thoroughly

Ist das mit grep möglich? Oder mit einer anderen Kombination von Werkzeugen?

539
Neil Baldwin

Versuchen Sie es mit grep -o

grep -oh "\w*th\w*" *

Edit: passend zu Phils Kommentar

Von den Dokumenten :

-h, --no-filename
    Suppress the prefixing of file names on output. This is the default
    when there is only  one  file  (or only standard input) to search.
-o, --only-matching
    Print  only  the matched (non-empty) parts of a matching line,
    with each such part on a separate output line.
740
Dan Midwood

Querverteilungssichere Antwort (einschließlich Windows minGW?)

grep -h "[[:alpha:]]*th[[:alpha:]]*" 'filename' | tr ' ' '\n' | grep -h "[[:alpha:]]*th[[:alpha:]]*"

Wenn Sie ältere Versionen von grep (wie 2.4.2) verwenden, die die Option -o nicht enthalten. Verwenden Sie das oben. Sonst verwenden Sie die einfachere Version, um die unten stehende Version zu erhalten.

Linux-verteilungsübergreifende sichere Antwort

grep -oh "[[:alpha:]]*th[[:alpha:]]*" 'filename'

Zusammenfassungen -oh gibt die Übereinstimmungen des regulären Ausdrucks mit dem Dateiinhalt (und nicht mit dem Dateinamen) aus, genau wie Sie davon ausgehen, dass regulärer Ausdruck in vim/etc funktioniert für dich! Solange Sie sich an POSIX und nicht an Perl-Syntax halten (siehe unten)

Mehr aus dem Handbuch für grep

-o      Print each match, but only the match, not the entire line.
-h      Never print filename headers (i.e. filenames) with output lines.
-w      The expression is searched for as a Word (as if surrounded by
         `[[:<:]]' and `[[:>:]]';

Der Grund, warum die ursprüngliche Antwort nicht für alle funktioniert

Die Verwendung von \w ist von Plattform zu Plattform unterschiedlich, da es sich um eine erweiterte "Perl" -Syntax handelt. Daher verwendet die Installation von grep, die auf POSIX-Zeichenklassen beschränkt ist, [[:alpha:]] und nicht das Perl-Äquivalent von \w. Siehe die Wikipedia-Seite zu regulären Ausdrücken für mehr

Letztendlich wird die obige POSIX-Antwort unabhängig von der Plattform (als Original) für grep viel zuverlässiger sein

Für die Unterstützung von grep ohne Option -o gibt das erste grep die relevanten Zeilen aus, das tr teilt die Leerzeichen in neue Zeilen auf, das letzte grep filtert nur die entsprechenden Zeilen.

(PS: Ich kenne inzwischen die meisten Plattformen, wäre für\w gepatcht worden ... aber es gibt immer solche, die hinterherhinken)

Gutschrift für die "-o" -Auslösung von @AdamRosenfield-Antwort

75
PicoCreator

Sie können Leerzeichen in Zeilenumbrüche und dann in grep übersetzen, z.

cat * | tr ' ' '\n' | grep th
39
Adam Rosenfield

Nur awk, keine Kombination von Werkzeugen erforderlich.

# awk '{for(i=1;i<=NF;i++){if($i~/^th/){print $i}}}' file
the
the
the
this
thoroughly
33
ghostdog74

Es ist einfacher als Sie denken. Versuche dies:

egrep -wo 'th.[a-z]*' filename.txt #### (Case Sensitive)

egrep -iwo 'th.[a-z]*' filename.txt  ### (Case Insensitive)

Woher,

 egrep: Grep will work with extended regular expression.
 w    : Matches only Word/words instead of substring.
 o    : Display only matched pattern instead of whole line.
 i    : If u want to ignore case sensitivity.
17

grep-Befehl nur für Abgleich und Perl

grep -o -P 'th.*? ' filename
10
Raghu

Ich war mit der schwer zu merkenden Syntax von awk unzufrieden, aber mir gefiel die Idee, ein Dienstprogramm dafür zu verwenden.

Es scheint, als ob ack (oder ack-grep, wenn Sie Ubuntu verwenden) dies einfach tun kann:

# ack-grep -ho "\bth.*?\b" *

the
the
the
this
thoroughly

Wenn Sie das Flag -h weglassen, erhalten Sie:

# ack-grep -o "\bth.*?\b" *

some-other-text-file
1:the

some-text-file
1:the
the

yet-another-text-file
1:this
thoroughly

Als Bonus können Sie das --output-Flag verwenden, um dies für komplexere Suchen mit der einfachsten Syntax zu tun, die ich gefunden habe:

# echo "bug: 1, id: 5, time: 12/27/2010" > test-file
# ack-grep -ho "bug: (\d*), id: (\d*), time: (.*)" --output '$1, $2, $3' test-file

1, 5, 12/27/2010
8
Beau
cat *-text-file | grep -Eio "th[a-z]+"
8
Mumbling Mac

Um alle Wörter zu suchen, die mit "icon-" beginnen, funktioniert der folgende Befehl perfekt. Ich benutze Ack hier, was dem grep ähnelt, aber mit besseren Optionen und schöner Formatierung.

ack -oh --type=html "\w*icon-\w*" | sort | uniq
4
Sandeep

Sie können auch pcregrep versuchen. Es gibt auch eine -w-Option in grep, aber in einigen Fällen funktioniert es nicht wie erwartet.

Aus Wikipedia :

cat fruitlist.txt
Apple
apples
pineapple
Apple-
Apple-fruit
fruit-Apple

grep -w Apple fruitlist.txt
Apple
apple-
Apple-fruit
fruit-Apple
3
Maciek Sawicki

Ich hatte ein ähnliches Problem und suchte nach grep/pattern regex und dem "Matched pattern found" als Ausgabe.

Am Ende habe ich egrep (gleiche Regex auf grep -e oder -G hat mir nicht das gleiche Ergebnis von egrep gegeben) mit der Option -o verwendet

ich denke, das könnte etwas Ähnliches sein (ich bin KEIN Regex-Meister):

egrep -o "the*|this{1}|thoroughly{1}" filename
3
keebOo

ripgrep

Hier ist das Beispiel mit ripgrep:

rg -o "(\w+)?th(\w+)?"

Es passt zu allen Wörtern, die mit th übereinstimmen.

0
kenorb
$ grep -w

Auszug aus der grep-Manpage:

-w: Nur die Zeilen auswählen, die Übereinstimmungen enthalten, die ganze Wörter bilden. Der Test besteht darin, dass der übereinstimmende Teilstring entweder am Anfang der Zeile stehen muss oder ein nicht aus Word bestehendes konstituierendes Zeichen vorangestellt ist.

0
pl1nk