Käytin tätä paljon, parannus, jonka yritän saavuttaa, on välttää kaikutiedostojen nimet, jotka eivät sopineet grep. Parempi tapa tehdä tämä?

 for file in `find . -name "*.py"`; do echo $file; grep something $file; done 

Kommentit

vastaus

 find . -name "*.py" -exec grep something {} \; -print  

tulostaisi tiedostonimen vastaavien rivien jälkeen.

 find . -name "*.py" -exec grep something /dev/null {} +  

tulosta tiedostonimi jokaisen vastaavan rivin eteen (lisätään /dev/null tapaukseen, jossa on vain yksi vastaava tiedosto nimellä grep ei tulosta tiedostonimeä, jos se on välittänyt vain yhden tutkittavan tiedoston. GNU-toteutus grep: lla on vaihtoehto vaihtoehto -H).

 find . -name "*.py" -exec grep -l something {} +  

tulostaa vain niiden tiedostojen nimet, joissa on vähintään yksi vastaava rivi.

Tulostaaksesi tiedostonimen ennen vastaavia rivejä, voit käyttää awk sen sijaan:

 find . -name "*.py" -exec awk " FNR == 1 {filename_printed = 0} /something/ { if (!filename_printed) { print FILENAME filename_printed = 1 } print }" {} +  

Tai soita grep kahdesti kullekin tiedostolle – vaikka ”d on vähemmän tehokas, koska se suorittaa vähintään yhden grep -komennon ja enintään kaksi kullekin tiedostolle (ja lue tiedoston sisältö kahdesti ):

 find . -name "*.py" -exec grep -l something {} \; \ -exec grep something {} \;  

Joka tapauksessa et halua käyttää silmukkaa find tällöin ja muista lainata muuttujat .

Jos haluat käyttää shell-silmukkaa, GNU-työkaluilla:

 find . -name "*.py" -exec grep -l --null something {} + | xargs -r0 sh -c " for file do printf "%s\n" "$file" grep something < "$file" done" sh  

(toimii myös FreeBSD: llä ja johdannaisilla).

Vastaa

I Jos käytät GNU grep -ohjelmaa, voit käyttää sen vaihtoehtoa -r tai --recursive tehdäksesi tämän yksinkertaisen haun sinulle:

 grep -r --include "*.py" -le "$regexp" ./ # for filenames only grep -r --include "*.py" -He "$regexp" ./ # for filenames on each match  

Tarvitset vain find, jos tarvitset edistyneemmät predikaatit.

Kommentit

  • GNU-version mukaan grep, grep voi etsiä symboleita tai hakemistoihin viittaavia linkkejä. Saatat löytää joitain muunnelmia muun tyyppisten ei-säännöllisten tiedostojen käsittelystä.

Vastaa

Sinä voi kertoa grep: lle sisällyttävän tiedostonimen lähtöön. Joten jos on ottelu, se näkyy konsolissa; jos tiedostossa ei ole vastaavuutta, tälle tiedostolle ei tulosteta riviä.

find . -name "*.py" | xargs grep -n -H something 

Kohdasta man grep:

-H Always print filename headers with output lines -n, --line-number Each output line is preceded by its relative line number in the file, starting at line 1. The line number counter is reset for each file processed. This option is ignored if -c, -L, -l, or -q is specified. 

Jos tiedostoissasi voi olla nimiä, joissa on välilyöntejä, sinun on vaihdettava putkea, jotta NUL-merkkejä käytetään erottajana. Koko komento näyttää nyt tältä:

find . -name "*.py" -print0 | xargs -0 grep -n -H something 

Vastaa

Voit kokeile jotain seuraavaa:

find . -name "*.py:" -exec grep -l {} \; 

Tämä exec grep -komento jokaiselle tiedostolle, löydetty find-komennolla ja sen tavallisella find-komento-ominaisuudella

Vastaa

Käytä -l-argumenttia.

for file in `find . -name "*.py"`; do grep -l something $file && grep something $file; done 

Löytävämpi käyttö olisi:

for file in $(find . -name "*.py" -exec grep -l something "{}" +); do echo "$file"; grep something $file; done 

vastaus

Siellä ovat grep vaihtoehtoja, jotka antavat tulokset oletusarvoisesti haluamassasi muodossa. Kaksi suosituinta, jotka tiedän, ovat ag (alias ”hopeanhaku”) ja ack. ag mainostetaan nopeammin vaihtoehtona ack.

$ ag "^\w+\s*\w+\(" ~/build/i3/src build/i3/src/display_version.c 58:void display_running_version(void) { build/i3/src/load_layout.c 42:static TAILQ_HEAD(focus_mappings_head, focus_mapping) focus_mappings = 518:json_content_t json_determine_content(const char *filename) { 575:void tree_append_json(Con *con, const char *filename, char **errormsg) { build/i3/src/x.c 64:CIRCLEQ_HEAD(state_head, con_state) state_head = 67:CIRCLEQ_HEAD(old_state_head, con_state) old_state_head = 70:TAILQ_HEAD(initial_mapping_head, con_state) initial_mapping_head = 97:void x_con_init(Con *con, uint16_t depth) { ... 

En voi näyttää sinua täällä, mutta tulos on siististi värillinen. Sain tiedostonimet oliivinvihreiksi, viivanumerot kullankeltaisiksi ja kunkin rivin vastaava kappale veripunaiseksi. Värit ovat kuitenkin muokattavissa.

Vastaa

Sähköpostiosoitettasi ei julkaista. Pakolliset kentät on merkitty *