Ik probeer een manier te vinden om mijn hele Linux-systeem te scannen op alle bestanden die een specifieke tekstreeks bevatten. Voor de duidelijkheid, ik zoek naar tekst in het bestand, niet in de bestandsnaam.
Toen ik zocht hoe ik dit moest doen, kwam ik deze oplossing twee keer tegen:
find / -type f -exec grep -H 'text-to-find-here' {} \;
Het werkt echter niet. Het lijkt elk bestand in het systeem weer te geven.
Komt dit in de buurt van de juiste manier om het te doen? Zo niet, hoe moet ik dat doen? Deze mogelijkheid om tekststrings in bestanden te vinden zou buitengewoon handig zijn voor sommige programmeerprojecten die ik aan het doen ben.
Antwoord 1, autoriteit 100%
Doe het volgende:
grep -rnw '/path/to/somewhere/' -e 'pattern'
-r
of-r
is recursief,-n
is regelnummer, en-w
staat voor overeenkomen met het hele woord.-l
(kleine letter L) kan worden toegevoegd om alleen de bestandsnaam van overeenkomende bestanden te geven.-e
is het patroon dat wordt gebruikt tijdens het zoeken
Samen met deze, --exclude
, --include
, --exclude-dir
vlaggen kunnen worden gebruikt voor efficiënt zoeken:
- Dit zoekt alleen in die bestanden met de extensie .c of .h:
grep --include=\*.{c,h} -rnw '/path/to/somewhere/' -e "pattern"
- Hiermee wordt het zoeken naar alle bestanden die eindigen op de extensie .o uitgesloten:
grep --exclude=\*.o -rnw '/path/to/somewhere/' -e "pattern"
- Voor mappen is het mogelijk om een of meer mappen uit te sluiten met de parameter
--exclude-dir
. Dit sluit bijvoorbeeld de dirs dir1/, dir2/ uit en ze komen allemaal overeen met *.dst/:
grep --exclude-dir={dir1,dir2,*.dst} -rnw '/path/to/somewhere/' -e "pattern"
Dit werkt heel goed voor mij, om bijna hetzelfde doel te bereiken als dat van jou.
Voor meer opties, check man grep
.
Antwoord 2, autoriteit 16%
U kunt grep -ilR
gebruiken:
grep -Ril "text-to-find-here" /
i
staat voor negeer hoofdletter (optioneel in jouw geval).r
staat voor recursief.l
staat voor “toon de bestandsnaam, niet het resultaat zelf”./
staat voor beginnen bij de root van uw machine.
Antwoord 3, autoriteit 3%
Je kunt ack gebruiken. Het is als grep voor broncode. Je kunt er je hele bestandssysteem mee scannen.
Doe gewoon:
ack 'text-to-find-here'
In uw hoofdmap.
Je kunt ook reguliere expressies gebruiken, het bestandstype specificeren, enz.
UPDATE
Ik heb zojuist The Silver Searcher ontdekt, die lijkt op ack, maar 3-5x sneller is en zelfs patronen negeert van een .gitignore
bestand.
Antwoord 4, autoriteit 2%
U kunt gebruiken:
grep -r "string to be searched" /path/to/dir
De r
staat voor recursief en zal dus zoeken in het opgegeven pad en ook in de submappen. Dit zal u de bestandsnaam vertellen en de regel in het bestand afdrukken waar de tekenreeks verschijnt.
Of een opdracht die lijkt op degene die u probeert (voorbeeld: ) voor het zoeken in alle javascript-bestanden (*.js):
find . -name '*.js' -exec grep -i 'string to search for' {} \; -print
Hiermee worden de regels in de bestanden afgedrukt waar de tekst verschijnt, maar de bestandsnaam wordt niet afgedrukt.
Naast dit commando kunnen we dit ook schrijven:
grep -rn “String om te zoeken” /pad/naar/map/of/bestand
-r: recursief zoeken
n: regelnummer wordt getoond voor overeenkomsten
Antwoord 5
U kunt dit gebruiken:
grep -inr "Text" folder/to/be/searched/
Antwoord 6
grep
(GNU of BSD)
U kunt de tool grep
gebruiken om recursief in de huidige map te zoeken, zoals:
grep -r "class foo" .
Opmerking: -r
– Recursief zoeken in submappen.
U kunt ook de globbing-syntaxis gebruiken om in specifieke bestanden te zoeken, zoals:
grep "class foo" **/*.c
Opmerking: door gebruik te maken van de globbing-optie ( **
), scant het alle bestanden recursief met een specifieke extensie of patroon. Als u deze syntaxis wilt inschakelen, voert u: shopt -s globstar
uit. Je mag ook **/*.*
gebruiken voor alle bestanden (exclusief verborgen en zonder extensie) of elk ander patroon.
Als je de foutmelding krijgt dat je argument te lang is, overweeg dan om je zoekopdracht te verfijnen, of gebruik in plaats daarvan de syntaxis find
, zoals:
find . -name "*.php" -execdir grep -nH --color=auto foo {} ';'
U kunt ook ripgrep
gebruiken.
ripgrep
Als je aan grotere projecten of grote bestanden werkt, moet je in plaats daarvan ripgrep
gebruiken, zoals:
rg "class foo" .
Bekijk de documenten, installatiestappen of broncode op de GitHub-projectpagina. sup>
Het is veel sneller dan enig ander hulpmiddel zoals GNU/BSD grep
, ucg
, ag
, sift
, ack
, pt
of vergelijkbaar, aangezien het bovenop Rust’s regex-engine die eindige automaten, SIMD en agressieve letterlijke optimalisaties gebruikt om het zoeken erg snel te maken.
Het ondersteunt negeerpatronen die zijn gespecificeerd in .gitignore
-bestanden, zodat een enkel bestandspad kan worden vergeleken met meerdere glob-patronen tegelijk.
U kunt algemene parameters gebruiken zoals:
-i
– Ongevoelig zoeken.-i
– Negeer de binaire bestanden.-w
– Zoek naar de hele woorden (in tegenstelling tot gedeeltelijke woordovereenkomst).-n
– Toon de lijn van je match.-c
/--context
(bijv.-C5
) – Verhoogt de context, zodat u de omringende code ziet.--color=auto
– Markeer de overeenkomende tekst.-h
– Toont de bestandsnaam waar de tekst wordt gevonden.-c
– Geeft het aantal overeenkomende regels weer. Kan worden gecombineerd met-h
.
Antwoord 7
Lijst met bestandsnamen die een bepaalde tekst bevatten
Ten eerste denk ik dat je -h
hebt gebruikt in plaats van -l
. U kunt ook proberen de tekst tussen aanhalingstekens toe te voegen, gevolgd door {} \
.
find / -type f -exec grep -l "text-to-find-here" {} \;
Voorbeeld
Stel dat u zoekt naar bestanden met de specifieke tekst “Apache-licentie” in uw directory. Het geeft resultaten weer die enigszins lijken op hieronder (de uitvoer zal verschillen op basis van de inhoud van uw directory).
bash-4.1$ find . -type f -exec grep -l "Apache License" {} \;
./net/java/jvnet-parent/5/jvnet-parent-5.pom
./commons-cli/commons-cli/1.3.1/commons-cli-1.3.1.pom
./io/swagger/swagger-project/1.5.10/swagger-project-1.5.10.pom
./io/netty/netty-transport/4.1.7.Final/netty-transport-4.1.7.Final.pom
./commons-codec/commons-codec/1.9/commons-codec-1.9.pom
./commons-io/commons-io/2.4/commons-io-2.4.pom
bash-4.1$
Hoofdlettergevoeligheid verwijderen
Zelfs als u de hoofdlettergebruik niet gebruikt, zoals “tekst” versus “TEKST”, kunt u de schakelaar -i
gebruiken om hoofdletters te negeren. U kunt hier meer details lezen.
Ik hoop dat dit je helpt.
Antwoord 8
Als uw grep
recursief zoeken niet ondersteunt, kunt u find
combineren met xargs
:
find / -type f | xargs grep 'text-to-find-here'
Ik vind dit makkelijker te onthouden dan het formaat voor find -exec
.
Hiermee worden de bestandsnaam en de inhoud van de overeenkomende regel weergegeven, bijvoorbeeld
/home/rob/file:text-to-find-here
Optionele vlaggen die u misschien wilt toevoegen aan grep
:
-i
– hoofdletterongevoelig zoeken-l
– voer alleen de bestandsnaam uit waar de overeenkomst werd gevonden-h
– voer alleen de regel uit die overeenkomt (niet de bestandsnaam)
Antwoord 9
grep -insr "pattern" *
i
: negeer onderscheid tussen hoofdletters in zowel de PATTERN als de invoerbestanden.n
: voeg voor elke uitvoerregel het 1-gebaseerde regelnummer toe in het invoerbestand.s
: onderdruk foutmeldingen over niet-bestaande of onleesbare bestanden.r
: lees alle bestanden onder elke map recursief.
Antwoord 10
Er is een nieuw hulpprogramma genaamd The Silversearcher
sudo apt install silversearcher-ag
Het werkt nauw samen met Git en andere VCS. Je krijgt dus niets in een .git of een andere directory.
U kunt gewoon
ag "Search query"
En het zal de taak voor u doen!
Antwoord 11
Hoe vind ik alle bestanden met specifieke tekst op Linux?
(…)Ik kwam deze oplossing twee keer tegen:
find / -type f -exec grep -H 'text-to-find-here' {} \;
Als je vind gebruikt zoals in je voorbeeld, voeg je beter -s
(--no-messages
) toe aan grep
, en 2>/dev/null
aan het einde van de opdracht om veel Toestemming geweigerd-berichten te voorkomen die zijn uitgegeven door grep
en find
:
find / -type f -exec grep -sH 'text-to-find-here' {} \; 2>/dev/null
find is de standaard tool voor het doorzoeken van bestanden – gecombineerd met grep bij het zoeken naar specifieke tekst – op Unix-achtige platforms. De opdracht find wordt vaak gecombineerd met xargs trouwens.
Er bestaan snellere en eenvoudigere tools voor hetzelfde doel – zie hieronder. Probeer ze beter uit, mits ze beschikbaar zijn op uw platform natuurlijk:
Sneller en gemakkelijkere alternatieven
RipGrep – snelste zoektool die er is:
rg 'text-to-find-here' / -l
ag 'text-to-find-here' / -l
ack:
ack 'text-to-find-here' / -l
Opmerking: u kunt ook 2>/dev/null
aan deze opdrachten toevoegen om veel foutmeldingen te verbergen.
Waarschuwing: tenzij je het echt niet kunt vermijden, zoek dan niet vanuit ‘/’ (de hoofdmap) om lang en inefficiënt zoeken te voorkomen!
Dus in de bovenstaande voorbeelden kunt u ‘/‘ beter vervangen door een submapnaam, b.v. “/home”, afhankelijk van waar je wilt zoeken…
Antwoord 12
Probeer:
find . -name "*.txt" | xargs grep -i "text_pattern"
Antwoord 13
Gebruik pwd
om te zoeken vanuit elke directory waarin u zich bevindt, teruglopend naar beneden
grep -rnw `pwd` -e "pattern"
Bijwerken
Afhankelijk van de versie van grep die je gebruikt, kun je pwd
weglaten. Op nieuwere versies lijkt .
het standaard geval te zijn voor grep als er geen map wordt gegeven
dus:
grep -rnw -e "pattern"
of
grep -rnw "pattern"
zal hetzelfde doen als hierboven!
Antwoord 14
grep
kan zelfs worden gebruikt als we niet naar een tekenreeks zoeken.
Gewoon hardlopen,
grep -RIl "" .
print het pad naar alle tekstbestanden af, d.w.z. bestanden die alleen afdrukbare tekens bevatten.
Antwoord 15
Silver Searcher is een geweldige tool, maar ripgrep is misschien nog beter.
Het werkt op Linux, Mac en Windows, en is geschreven op Hacker News een paar van maanden geleden (dit heeft een link naar de blog van Andrew Gallant met een GitHub-link):
Ripgrep Een nieuwe opdrachtregelzoekfunctie
Antwoord 16
Als je strikt find
wilt gebruiken, gebruik dan find + grep
:
find /path/to/somewhere/ -type f -exec grep -nw 'textPattern' {} \;
Stappen:
- Gebruik
find
om bestanden te zoeken, - Voer
grep
uit op allemaal.
Dit geeft je de kracht van find
om bestanden te vinden.
- Gebruik
-name Pattern
als je alleen bepaalde bestanden wiltgrep
:
find /path/to/somewhere/ -type f -name \*.cpp -exec grep -nw 'textPattern' {} \;
U kunt verschillende opties van find
gebruiken om het zoeken naar bestanden te verbeteren.
Antwoord 17
Hier zijn de verschillende lijsten met opdrachten die kunnen worden gebruikt om bestanden te zoeken.
grep "text string to search” directory-path
grep [option] "text string to search” directory-path
grep -r "text string to search” directory-path
grep -r -H "text string to search” directory-path
egrep -R "word-1|word-2” directory-path
egrep -w -R "word-1|word-2” directory-path
Antwoord 18
find /path -type f -exec grep -l "string" {} \;
Uitleg van opmerkingen
find is een commando waarmee je bestanden en andere objecten zoals mappen en links in submappen van een bepaald pad kunt vinden. Als u geen masker opgeeft waaraan bestandsnamen moeten voldoen, worden alle directory-objecten opgesomd.
-type f specifies that it should proceed only files, not directories etc.
-exec grep specifies that for every found file, it should run grep command, passing its filename as an argument to it, by replacing {} with the filename
Antwoord 19
Ik hoop dat dit je helpt…
De grep
een beetje uitbreiden om meer informatie in de uitvoer te krijgen, bijvoorbeeld om het regelnummer in het bestand te krijgen waar de tekst zich bevindt, kan als volgt:
find . -type f -name "*.*" -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searthtext"
En als u een idee heeft wat het bestandstype is, kunt u uw zoekopdracht verfijnen door bestandstype-extensies op te geven waarnaar moet worden gezocht, in dit geval .pas
OF .dfm
bestanden:
find . -type f \( -name "*.pas" -o -name "*.dfm" \) -print0 | xargs --null grep --with-filename --line-number --no-messages --color --ignore-case "searchtext"
Korte uitleg van de opties:
.
in defind
specificeert uit de huidige directory.-name
“*.*
” : voor alle bestanden
( -name “*.pas
” -o -name “*.dfm
” ) : Alleen de*.pas
OF*.dfm
bestanden, OF gespecificeerd met-o
-type f
geeft aan dat u op zoek bent naar bestanden-print0
en--null
aan de andere kant van de|
(pipe) zijn de cruciale, ze geven de bestandsnaam door van defind
naar degrep
ingebed in dexargs
, waardoor bestandsnamen MET spaties in de bestandsnamen kunnen worden doorgegeven, waardoor grep het pad en de bestandsnaam kan behandelen als één tekenreeks, en niet op elke spatie opsplitsen.
Antwoord 20
Ik ben gefascineerd door hoe eenvoudig grep het maakt met ‘rl’:
grep -rl 'pattern_to_find' /path/where/to/find
-r to recursively find a file / directory inside directories..
-l to list files matching the 'pattern'
Gebruik ‘-r’ zonder ‘l’ om de bestandsnamen te zien gevolgd door tekst waarin het patroon wordt gevonden!
grep -r 'pattern_to_find' /path/where/to/find
Het werkt gewoon perfect…
Antwoord 21
Een simpele find
kan handig zijn. alias het in uw ~/.bashrc
-bestand:
alias ffind find / -type f | xargs grep
Start een nieuwe terminal en geef uit:
ffind 'text-to-find-here'
Antwoord 22
Probeer:
find / -type f -exec grep -H 'text-to-find-here' {} \;
die alle bestandssystemen doorzoekt, omdat /
de hoofdmap is.
Voor gebruik in de thuismap:
find ~/ -type f -exec grep -H 'text-to-find-here' {} \;
Voor huidige map:
find ./ -type f -exec grep -H 'text-to-find-here' {} \;
Antwoord 23
grep is je goede vriend om dit te bereiken.
grep -r <text_fo_find> <directory>
Als u niet geïnteresseerd bent in hoofdlettergebruik van de tekst die u zoekt, gebruik dan:
grep -ir <text_to_find> <directory>
Antwoord 24
Ik heb een Python-script geschreven dat iets soortgelijks doet. Dit is hoe je dit script moet gebruiken.
./sniff.py path pattern_to_search [file_pattern]
Het eerste argument, path
, is de directory waarin we recursief zullen zoeken. Het tweede argument, pattern_to_search
, is een reguliere expressie die we in een bestand willen zoeken. We gebruiken de reguliere expressie-indeling die is gedefinieerd in de Python re
bibliotheek. In dit script komt de .
ook overeen met de nieuwe regel.
Het derde argument, file_pattern
, is optioneel. Dit is een andere reguliere expressie die werkt op een bestandsnaam. Alleen die bestanden die overeenkomen met deze reguliere expressie worden in aanmerking genomen.
Als ik bijvoorbeeld Python-bestanden wil zoeken met de extensie py
met Pool(
gevolgd door het woord Adaptor
, doe ik het volgende ,
./sniff.py . "Pool(.*?Adaptor" .*py
./Demos/snippets/cubeMeshSigNeur.py:146
./Demos/snippets/testSigNeur.py:259
./python/moose/multiscale/core/mumbl.py:206
./Demos/snippets/multiComptSigNeur.py:268
En voila, het genereert het pad van overeenkomende bestanden en het regelnummer waarop de overeenkomst is gevonden. Als er meer dan één overeenkomst is gevonden, wordt elk regelnummer aan de bestandsnaam toegevoegd.
Antwoord 25
Er is een ack
tool die precies doet wat je zoekt.
http://linux.die.net/man/1/ack
ack -i search_string folder_path/*
U kunt -i
negeren voor hoofdlettergevoelig zoeken
Antwoord 26
Gebruik:
grep -c Your_Pattern *
Dit geeft aan hoeveel exemplaren van uw patroon er in elk van de bestanden in de huidige map staan.
Antwoord 27
Zoeken naar de tekenreeks en alleen die regel uitvoeren 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 weer te geven die de zoekreeks bevat:
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;
Antwoord 28
Alle eerdere antwoorden suggereren grep en zoeken. Maar er is een andere manier: gebruik Midnight Commander
Het is een gratis hulpprogramma (30 jaar oud, bewezen door de tijd) dat visueel is zonder een GUI te zijn. Het heeft talloze functies en het vinden van bestanden is er slechts één van.
Antwoord 29
Het onderstaande commando werkt prima voor deze aanpak:
find ./ -name "file_pattern_name" -exec grep -r "pattern" {} \;
Antwoord 30
Vermijd het gedoe en installeer ack-grep. Het elimineert veel problemen met toestemming en offertes.
apt-get install ack-grep
Ga vervolgens naar de map waarin u wilt zoeken en voer de onderstaande opdracht uit
cd /
ack-grep "find my keyword"