Kommentit
Vastaa
GNU grep
Pitäisi olla hieman nopeampi, koska toinen grep
voi toimia tiedostoluettelossa.
grep -lZ "foo" * | xargs -0 grep -l "321"
POSIX-grep ja etsi
find
on hyödyllisempi, jos haluat etsiä rekursiivisista hakemistoista (tällöin menetät -mindepth
ja -maxdepth
vaihtoehdot.
find . -mindepth 1 -maxdepth 1 -type f -exec grep -q "foo" {} \; -exec grep -l "321" {} +
Kommentit
-
-r
toimi hyvin ensimmäisellägrep
, jotta GNU-ratkaisu olisi rekursiivinen minulle, sen sijaan, että käyttäisit POSIX-riviä kaikkien niiden kanssaexec
s
Vastaa
Voit tehdä tämän lyhyellä komentosarjalla:
for FILE in * do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE done
Voit tehdä tämän myös yhdellä rivillä:
for FILE in *; do grep -q foo $FILE && grep -q 321 $FILE && echo $FILE; done
grep
palauttaa arvon 0 (true), jos se löysi merkkijonon ja komennot erottava &&
tarkoittaa, että toinen toimii vain, jos ensimmäinen oli totta. -q
-vaihtoehto varmistaa, että grep
ei tuota mitään.
Kaiku toimii vain, jos molemmat merkkijonot olivat löytyy samasta tiedostosta.
Ajattelin eri tapaa tehdä se. Tämä tapa on todennäköisesti tehokkaampi, jos kyseiset tiedostot ovat suurempia kuin asennettu RAM-muistisi, koska sen täytyy vain grep
käydä läpi jokainen tiedosto kerran.
for FILE in * do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE done
ja yksirivinen versio:
for FILE in *; do test $(egrep -o "foo|321" $FILE | uniq | sort | uniq | wc -l) -eq 2 && echo $FILE; done
kommentit
- Tehokkaampaa ratkaisua varten: entä jos tiedostossa on " foo foo "?
- Että ' s mitä
uniq | sort | uniq
on tarkoitettu. " foo foo " on lopulta yksi rivi, mutta " foo 321 " on loppujen lopuksi kaksi riviä, koskagrep -o
tuottaa kaikki löydetyt merkkijonot erillisillä riveillä, vaikka ne aloittaisivat samalla rivillä. - Jos tiedostoista tulee niin suuria, että haarautuminen vähintään kuusi kertaa tiedostoa kohden on OK, on luultavasti järkevää käyttää sen sijaan awk-tiedostoa, jotta tiedostoja ei tarvitse etsiä loppuun asti.
- @Ladadadada sai se. 🙂
- @HaukeLaging
grep -q
jagrep -l
ei etsi tiedoston loppuun: ne poistuvat heti koska ottelu löytyy. Se saa minut miettimään, miksi ensimmäinen ratkaisu ei ole ' tfor FILE in *; do grep -q foo "$FILE" && grep -l 321 "$FILE"; done
vastaus
Outoa. Minulle molemmat vaihtoehdot toimivat (grep (GNU grep) 2.13):
grep "foo\|321" grep -E "foo|321"
Muokkaa 1 – näytä vain molempien vastaavuuksien tiedostot
for file in *
-vastaus toimii, mutta siitä voi tulla suorituskykyinen painajainen (suurille tiedostoille ): vähintään kaksi prosessia tiedostoa kohden. Tämä on nopeampaa (GNU-maailmassa):
find . -type f -print0 | xargs -0 -r grep --files-with-matches --null -- string1 | xargs -0 -r grep --files-with-matches -- string2
Merkkijonon 1 pitäisi olla se, joka johtaa vähemmän otteluihin.
Kommentit
- Kysyjä etsii tuloksen palautuvan tosi vain, jos tiedosto sisältää molemmat merkkijonot sen sijaan, että se vain sopisi vähintään yhteen.
- Pidän siitä
--files-with-matches
-vaihtoehto. Lukekaa se vain man-sivulta ja se saa grepin lopettamaan ensimmäisen haun löytymisen vuoksi, mikä tarkoittaa, että se ' on erittäin tehokas suurille tiedostoille, jos ottelu tapahtuu aikaisin. Siinä sanotaan myös, että lyhyt vaihtoehto-l
on POSIXin määrittelemä, joten sitä voidaan käyttää GNU-maailman ulkopuolella. - @Ladadadada Tehokkuus ei ole etu -q kuitenkin. Mainitsemalla GNU: ta en ollut ' ajatellut –file-with-matchs vaan -0 / –null.Mikä vain tulee mieleeni: polunimen laajennus sisältää aakkosellisen lajittelun (todella huono: Näyttää siltä, että se voidaan ' ei edes sammuttaa), joten
for file in *
ei enää todellakaan ole hauskaa. - Tehokkuuden optimointi olisi todellakin erilainen muutamille suurille tiedostoille verrattuna paljon pieniin ja
*
vain ei ole ' ei toimi lainkaan muutaman tuhannen tiedoston jälkeen. - @Ladadadada Se ei ' t toimii osana ulkoisen komennon komentoriviä:
grep foo *
Muttafor file in *
on kuoren sisäinen rakenne, joten oletan että komentorivirajaa ei voida käyttää tässä.
Vastaa
Periaatteessa kaikkien tiedostojen löytäminen tietyn mukaan lukien merkkijono hakemistossa, voit käyttää tätä:
grep -lir "pattern" /path/to/the/dir
-
-l
: tehdäksesi skannauksen pysähtyy ensimmäisellä ottelulla -
-i
: ohitetaan sekä kuvio- että syötetiedostojen kirjainkoon erot -
-r
: etsi kaikki hakemiston tiedostot rekursiivisesti
Jos haluat etsiä kahta mallia, kokeile tätä:
grep -lr "321" $(grep -lr "foo" /path/to/the/dir)
Kommentit
- Tavalliset tylsät kommentit siitä, että
$()
ei käsittele välilyöntejä, ovat voimassa. Käytännössä tämä komento toimii yhdellä linjassa kuoressa.
Vastaus
Pitäisi olla
grep -e "foo" -e "321" *
Käytä -e useille kuvioille
MUOKKAA
Jos tarvitset molempia:
grep -e ".*foo.*321.*" *
Jos järjestyksellä ei ole väliä:
grep -e ".*foo.*321.*" ".*321.*foo.*" *
Kommentit
- Tämä ei anna vastausta kysymykseen. Jätä kommentti kirjoittajan kritiikkiin tai pyydä selvennystä kirjoittajalta.
- @mdpc Mielestäni se antaa vastauksen. Mikä saa sinut ajattelemaan erilaista?
- @HaukeLaging Koska se palaa, jos jompikumpi kuvio sopii. OP etsii tapausta, jossa se palaa tosi vain, jos molemmat löytyy tiedostosta.
- Ymmärrän, että löydän vain tiedostot, joissa molemmat merkkijonot sisältävät samalla rivillä (I älä ' usko. vastaa oletuksena uusia rivejä)
321
bar
-kohdan sijaan: – D