Vraag Hoe u de "grep" -opdracht gebruikt om tekst te zoeken, inclusief submappen


Ik wil alle bestanden vinden die een specifieke reeks tekst bevatten. De grep command werkt, maar ik weet niet hoe ik het voor elke directory moet gebruiken (ik kan het alleen voor mijn huidige directory doen). Ik probeerde het te lezen man grep, maar het leverde geen hulp op.


292
2017-08-01 11:38


oorsprong


grep -RIn <yor pattern> * Zoekt in de huidige mappen in alle tekstbestanden. Weet niet zeker hoe ik mijn zoekopdracht recursief moet doen in bestandspatronen zoals * .C met alleen grep
Wildcard met --include="*.C" optie, @ user311346, dankzij @Lekensteyn. - Bob Stein
Gebruik de combinatie zoeken en grepen om recursief bestanden te zoeken naar een tekenreeks in huidige en alle submappen. Controleer dit wilddiary.com/find-files-containing-my-text - Drona


antwoorden:


Het zou beter zijn om te gebruiken

grep -rl "string" /path

waar

  • -r (of --recursive) optie wordt gebruikt om ook alle submappen van te doorlopen /path, terwijl
  • -l (of --files-with-matches) optie wordt gebruikt om alleen bestandsnamen van overeenkomende bestanden af ​​te drukken, en niet de overeenkomende regels (dit zou ook de snelheid kunnen verbeteren, gezien het feit dat grep stop met het lezen van een bestand bij de eerste match met deze optie).

375
2017-08-01 11:55



Als 'string' een tekstpatroon is om te vinden, is het beter om die functionaliteit te gebruiken, anders kan iemand problemen krijgen als de tekenreeks een punt of speciaal teken bevat dat betekenis heeft in reguliere expressies en niet alleen maar een punt dat als een tekenreeks moet worden gevonden , zoals het is. Dan zou ik gebruiken -rlF switches, -F voor "fixed string" (en niet regexp - bijvoorbeeld). Natuurlijk, als de taak regexps gebruikte, excuseer me dan. Natuurlijk, dezelfde theorie ook zonder -r, ik zie vaak dat mensen grep-zoekopdrachten "tekst" aannemen en het kan problemen veroorzaken welke speciale die iets als een regexp betekenen. - LGB
Er is ook de -i vlag die case negeert. - Marco Ceppi♦
Ik zou alleen de --recursive optie, er zijn vele opties en gebruiksscenario's waar je over kunt praten. Ik begon met het door @dmityugov geaccepteerde antwoord en aangepast om zonder te werken find. - enzotib
@ N.N .: done :-) - enzotib
@ScottBiggs: met de optie --include '*.h' - enzotib


Als u op zoek bent naar lijnen die overeenkomen in bestanden, is mijn favoriete opdracht:

grep -Hrn 'search term' path/to/files
  • -H zorgt ervoor dat de bestandsnaam wordt afgedrukt (geïmpliceerd wanneer meerdere bestanden worden doorzocht)
  • -r doet een recursieve zoekopdracht
  • -n zorgt ervoor dat het regelnummer wordt afgedrukt

path/to/files kan zijn . om in de huidige map te zoeken

Verdere opties die ik erg handig vind:

  • -I negeer binaire bestanden (complement: -a behandel alle bestanden als tekst)
  • -F traktatie search term als een letterlijke, geen reguliere expressie
  • -i doe een niet-hoofdlettergevoelige zoekactie
  • --color=always om kleuren te forceren, zelfs wanneer er doorheen wordt geboord less. Maken less kleuren ondersteunen, moet u de -r keuze:

    grep -Hrn search . | less -r
    
  • --exclude-dir=dir handig voor het uitsluiten van mappen zoals .svn en .git.

Example output


136
2017-08-01 12:27



-H op een map is overbodig, als er meer dan één bestand is, zoals waarschijnlijk is. In feite zegt de man-pagina -H, --with-filename: Print the file name for each match. This is the default when there is more than one file to search. - enzotib
Ik wist dat niet, het werkte altijd zoals ik verwachtte. Het is mijn standaardopdracht bij het zoeken naar bestanden. - Lekensteyn
Is er een manier om alleen bestanden te overwegen met een, laten we zeggen, een extensie (en om dit te combineren met -r)? - user2413
@ user2413 Probeer --include '*.*' - Lekensteyn
@enzotib Gewoon een FYI: ik krijg niet de mooie zuivere uitvoer van elke regel in elk bestand waar mijn tekst verschijnt met -rln nor -rl, maar ik doe met -Hrn. Overbodig of niet, het lijkt op de bovenstaande schermafbeelding met de -Hrn-opties. Het lijkt ook niet -n werkt zonder -H. - SgtPooki


Ik geloof dat je zoiets als dit kunt gebruiken:

find /path -type f -exec grep -l "string" {} \;

Uitleg van opmerkingen

find is een opdracht waarmee u bestanden en andere objecten zoals mappen en koppelingen in submappen van een bepaald pad kunt vinden. Als u geen masker opgeeft waaraan bestandsnamen moeten voldoen, worden alle mapobjecten geteld.

  • -type f geeft aan dat alleen bestanden moeten worden verwerkt, geen mappen, enz.
  • -exec grep specificeert dat voor elk gevonden bestand, het de opdracht grep moet uitvoeren, de bestandsnaam moet doorgeven als een argument, door te vervangen {} met de bestandsnaam

21
2017-08-01 11:48



Alleen voor degenen die niet weten, toe te voegen -name '*.py' beperkt de overeenkomsten tot bestanden die eindigen op '.py'. - Daniel F
Ik vind het leuk dat dit betrekking heeft op clients die geen -R hebben geïmplementeerd in hun grep-opdracht. - Aviose


Mijn standaardopdracht is

grep -Rin string *

Ik gebruik een hoofdletter 'R' omdat ls gebruikt het voor recursief. Omdat grep beide accepteert, geen reden om het niet te gebruiken.

EDIT: blijkbaar per HVNSweeting -R zal symlinks waar volgen als -r zal niet.


17
2017-08-01 14:43



Om ook in verborgen bestanden te zoeken, voer shopt -s dotglob (onthouden -s als "set"). Wees voorzichtig bij het verwijderen van bestanden. Als je dotglob hebt ingeschakeld, rm -r * verwijdert alles in de huidige map, maar ook de map erboven omdat .. wedstrijden. Gebruik dotglob uit te schakelen shopt -u dotglob ( "Uitgeschakeld"). De wijzigingen zijn echter tijdelijk, het is alleen van toepassing op de huidige shell. - Lekensteyn
Ik was dit vergeten. Is er een manier om het in te stellen voor één regel? zoiets als shopt -s dotglob & <grep cmd> & shopt -y dotglob alleen handiger? Op deze manier hoeven we ons geen zorgen te maken over het opnieuw instellen ervan - user606723
Het is waarschijnlijk ook gemakkelijker te gebruiken grep -Rin string . in de meeste van deze gevallen. Ik gebruik gewoon * omdat het op een meer natuurlijke manier lijkt te komen. - user606723
als je recursieve grep gebruikt, kun je gewoon beginnen met "." in plaats van "*". geen dotglob nodig. - Michał Šrajer
stem dit op, een ding vermeldt niet in manpage is R zal symbolische links volgen, r doet niet - HVNSweeting


Als je bereid bent iets nieuws te proberen, geef dan ack een schot. De opdracht om recursief in de huidige map te zoeken string is:

ack string

Installatie is vrij eenvoudig:

curl http://betterthangrep.com/ack-standalone > ~/bin/ack && chmod 0755 !#:3

(Mits je de map al hebt ~/bin en het is bij voorkeur in jouw PATH.)


11
2017-08-01 15:09



Of gewoon apt-get installeer ack-grep (, en voeg alias ack = ack-grep toe aan je .bashrc) - markijbema
Wat doen de laatste parameters voor de chmod commando doen? Zijn ze specifiek voor chmod of zijn ze bash gerelateerd (de !#:3 een deel)? - Elliott Darfink
@ElliottDarfink Dat gebruikt Bash's geschiedenis functie - ! is een evenement-aanduiding. Ze zijn behoorlijk krachtig om herhalingen te voorkomen. !#:3 verwijst naar het derde token van de opdrachtregel tot nu toe, d.w.z. ~/bin/ack in dit geval. - Konrad Rudolph


De opdracht rgrep is speciaal voor deze behoefte

Indien niet beschikbaar, kunt u het zo krijgen

mkdir -p ~/bin
cd ~/bin
wget http://sdjf.esmartdesign.com/files/rgrep
chmod +x rgrep

U kunt rechtstreeks instellen op uw standaard grep-opties zoals hierboven beschreven.

Ik persoonlijk gebruik

[[  ${#args} -lt 5 && "${args//[[:space:]]/}" == "-i" ]] && args="-Hin"
args="${args:--Hns} --color=auto"

gerelateerd onderwerp: hoe gebruik je altijd rgrep met kleur


3
2018-01-02 13:58



rgrep wordt geleverd door het grep-pakket dat standaard in Ubuntu is geïnstalleerd. - karel


Update 2:

Deze regel met opdrachten gebruikt find en grep lost het probleem op:

$ find path_to_search_in -type f -exec grep -in searchString {} 2> /dev/null +

--color=<always or auto> voor gekleurde output:

$ find path_to_search_in -type f \
            -exec grep --color=always -in searchString {} 2>/dev/null +

Voorbeeld:

$ find /tmp/test/ -type f -exec grep --color=auto -in "Search string" {} 2>/dev/null +

Een voorbeeld van een run in de onderstaande snapshot: snap1


Update 1:

U kunt de volgende code proberen; als een functie in uw .bashrcof .bash_aliases of in een script:

wherein () 
{ 
    for i in $(find "$1" -type f 2> /dev/null);
    do
        if grep --color=auto -i "$2" "$i" 2> /dev/null; then
            echo -e "\033[0;32mFound in: $i \033[0m\n";
        fi;
    done
}

Gebruik: wherein /path/to/search/in/ searchkeyword

voorbeeld:

$ wherein ~/Documents/ "hello world"

(Opmerking: zoals gesuggereerd in de opmerkingen hieronder door @enzotib, werkt dit niet met bestanden / mappen inclusief spaties in hun naam.)


Oorspronkelijke post

Ga als volgt te werk om naar de reeks te zoeken en voer alleen die regel uit met de zoekreeks:

$ for i in $(find /path/of/target/directory -type f); do \
    grep -i "the string to look for" "$i"; done

bijv .:

$ for i in $(find /usr/share/applications -type f); \
    do grep -i "web browser" "$i"; done

Om de bestandsnaam met de zoekreeks weer te geven:

$ for i in $(find /path/of/target/directory -type f); do \
    if grep -i "the string to look for" "$i" > /dev/null; then echo "$i"; fi; done;

bijv .:

$ for i in $(find /usr/share/applications -type f); \
    do if grep -i "web browser" "$i" > /dev/null; then echo "$i"; \
    fi; done;

2
2018-01-25 11:11



Mislukt bestandsnamen die spaties bevatten. Het falen wordt verborgen door het feit dat stderr niet wordt getoond. - enzotib
@enzotib bedankt voor het wijzen van dat .. dat is nog steeds niet opgelost voor de gespecificeerde functie .. Ik heb echter nog een one-liner toegevoegd .. - precise
Nu is het antwoord vergelijkbaar met dat van @dmityugov. - enzotib
ja, maar in die zin zijn de meeste antwoorden op deze pagina die u gebruikt vergelijkbaar grep, daarnaast dat de subset is die gebruikt find met grep... maar als je verschillende schakelaars en tweaks als een duidelijk antwoord accepteert, zal de mijne waarschijnlijk ook hier passen. Of ben je anders? de laatste update doet wat ik graag zou willen in mijn zoekopdracht: bestandsnamen met regels met zoeksleutel en regelnr. too :) and coloured output and error filter for better readability .. - precise


Ik doe dit met xargs, een zeer ondergewaardeerde opdracht

find ./ -type f -print0 | xargs -0 grep 'string_you_are_looking_for'

find ./ geeft u een recursieve lijst van alle bestanden in een huidige map dan pijp je het naar xargs die de grep-opdracht uitvoert voor elk van die bestanden


1
2017-08-01 15:30



Gebruik makend van xargs zonder -print0 optie om find en -0 optie om xargs is verouderd, het zal mislukken op bestandsnamen die spaties bevatten. - enzotib
@enzotib Ik heb het antwoord bewerkt zoals u had voorgesteld.- gelieve te bekijken en als het moet worden bewerkt en gecorrigeerd, zal ik u graag opnieuw bewerken. dank je - αғsнιη
@KasiyA: het is nu in orde, mijn downvote verwijderd. - enzotib


Ik weet dat hier veel antwoorden zijn, maar hier is een alternatief als u andere beperkingen wilt toevoegen bij het doorzoeken van de bestanden:

find . -type f -exec grep --quiet string_to_look_for {} ';' -print

Dit werkt omdat grep zal 0 retourneren als het een resultaat heeft gevonden, anders 1. U kunt bijvoorbeeld bestanden van 1 MB groot vinden en iets bevatten:

find . -type f -exec grep --quiet string_to_look_for {} ';' -size 1M -print

Voor meerdere vereisten wilt u waarschijnlijk de optimizer-vlag gebruiken -O dat bestaat in GNU grep.


0
2018-03-11 13:56





Een script (find-in-code) om te zoeken in C, CPP-code:

#!/bin/sh

find . \( -iname "*.c" -o -iname "*.cpp" -o -iname "*.h" \) -type f -print0 | xargs -0 grep --color -n "$1"

Gebruik:

find-in-code "search string"

0
2018-06-11 16:49





grep (GNUof BSD)

Je kunt gebruiken grep hulpmiddel om recursief de huidige map met te doorzoeken -r parameter, zoals:

grep -r "pattern" .

Notitie: -r - Recursief zoeken in submappen.

Om binnen specifieke bestanden te zoeken, kunt u a gebruiken globbing-syntaxis zoals:

grep "class foo" **/*.c

Opmerking: door te gebruiken globbing optie (**), scant het alle bestanden recursief met specifieke extensie of patroon. Ga als volgt te werk om deze syntaxis in te schakelen: shopt -s globstar. Je mag ook gebruiken **/*.* voor alle bestanden (exclusief verborgen en zonder extensie) of een ander patroon.

Als je de fout hebt dat je argument te lang is, overweeg dan om je zoekopdracht te verfijnen of te gebruiken find syntaxis zoals:

find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'

Als alternatief gebruiken ripgrep.

ripgrep

Als u aan grotere projecten of grote bestanden werkt, moet u dit gebruiken ripgrep in plaats daarvan, zoals:

rg "pattern" .

Controleer de documentatie, installatiestappen of broncode op de GitHub projectpagina.

Het is veel sneller dan welk ander hulpmiddel dan ook GNU/BSD  grep, ucg, ag, sift, ack, pt of vergelijkbaar, omdat het bovenop is gebouwd Rust's regex-motor die eindige automaten, SIMD en agressieve letterlijke optimalisaties gebruikt om het zoeken erg snel te maken.

Het ondersteunt negeerpatronen die zijn opgegeven in .gitignore bestanden, zodat een enkel bestandspad kan worden vergeleken met meerdere glob-patronen tegelijkertijd.


U kunt de gemeenschappelijke parameters gebruiken, zoals:

  • -i - Ongevoelig zoeken.
  • -I - Negeer de binaire bestanden.
  • -w - Zoek naar de hele woorden (in tegenstelling van gedeeltelijke woordvergelijking).
  • -n - Laat de regel van je wedstrijd zien.
  • -C/--context (B.v. -C5) - Verhoogt de context, zodat u de omringende code ziet.
  • --color=auto - Markeer de overeenkomende tekst.
  • -H - Geeft de bestandsnaam weer waar de tekst is gevonden.
  • -c - Geeft het aantal overeenstemmende lijnen weer. Kan worden gecombineerd met -H.

0
2018-04-11 11:21