[megoldva] egrep ÉS kapcsolat

Fórumok

Hali,

Egyszerűen nem hiszem el, hogy egrep-pel csak VAGY kapcsolattal tudok keresni egy szöveges fájlban.

Tudna valaki segíteni, hogy az alábbi helyett:


grep -irE "hello|szia" .

milyen olyan grep paranccsal tudnám azt elérni, hogy akkor dobja a fájl nevét, ha mindkét szó (minta) szerepel a fájlban? Mert ugye a fenti minden olyan fájlt dob, amelyben VAGY a hello szó, VAGY a szia szó szerepel. Nekem ez ÉS kapcsolattal kellene.

Már minden man-t meg google forrást átnéztem (legalábbis amit találtam ;) )
Köszi.

Hozzászólások


find   -exec grep -q egyik '{}' \; -and \
       -exec grep -q masik '{}' \; -and \
       -exec echo '{}' \;

1. grep "hello"|grep "szia" -na jó ez tényleg nem a legtutibb.
2. grep -E "hello.*szia|szia.*hello" ez meg csak akkor igaz ha egy sorban vannak.

próbálkozom find-dal....

"Már minden man-t meg google forrást átnéztem (legalábbis amit találtam ;) )"

Pedig a manban az igazság:

man grep:
grep searches the named input FILEs (or standard input if no files are named, or the file name - is given) for lines containing a match to the given PATTERN. By default, grep prints the matching lines.

Összefoglalva: egy greppel sehogy.


awk 'BEGIN {
            foo=0; 
            bar=0; 
           }
     /foo/ {
            foo=1; 
           }
     /bar/ {
            bar=1; 
           }
     END   {
            if ( foo+bar=2 ) {
                print FILENAME
            }
           }' My_file.lst

Vagy két grep-pel és a test-tel trükközve:


[ $( grep -c "foo" myfile.lst ) -gt 0  -a $( grep -c "bar" myfile.lst ) -gt 0 ] && echo myfile.lst

Esetleg a tr-t is bevetve egy egrep-et használva:


[ $(tr "\n" " " < myfile.lst | egrep -c "foo.*bar|bar.*foo" ) -gt 0 ] && echo myfile.lst

satöbbi...

A topik címe "egrep ÉS kapcsolat".
"... nem hiszem el, hogy egrep-pel csak VAGY kapcsolattal tudok keresni ..."
"milyen olyan grep paranccsal tudnám azt elérni, hogy ..."

A válasz erre még mindig az, hogy egy greppel sehogy. Awk, gét grep stb. segítségével természetesen elérhető a cél, ezt szépen meg is mutatod, de nem ez volt a topiknyitó kérése.

Ez nagy félreértés. A grep alapvetően nem a file nevét, hanem a megadott mintára illeszkedő sorokat írja ki, és ezen kívül opcionálisan a file nevét is. Tehát ha egy sorban valamelyik minta szerepel, akkor egy file esetén (-H nélkül) csak az illeszkedő sort írja ki, több file esetén a sort és a file nevét is, tehát egy file neve több, külön sorokban lévő illeszkedő minta esetén többször szerepel. Ha csak a file neve kellene, akkor a ":" előtti részt ki kell vágni és egyedivé tenni(pl.: cut, sort -u).


# cat textfile
abcd
efgh
ijkl

# grep -E 'a|j' textfile
abcd
ijkl

# grep -HE 'a|j' textfile
textfile:abcd
textfile:ijkl

"... tehát többször végig kell néznie a fájlt."
Nem. Egyszer olvassa végig, és soronként vizsgálja, hogy a megadott minták illeszkednek-e rá. Tehát nem mintánként egyszer olvassa végig, hanem egy olvasás során keres több minta között.

"Amúgy jó lenne nekem bármilyen grep ;)"
Azért összejött már itt egypár megoldás a hozzászólók (zamboriz, dromie, zeller) jóvoltából. Az egy parancsos megoldásként pedig zeller javasolta az agrepet.

Most jutottam el az "agrep"-ig, ez a megoldás, Köszönöm mindenkinek a segítséget.

Tehát ha azt akarom, hogy a grep dobjon minden olyan fájlt, amelyben szerepel a "hello" és "szia" kulcsszavak mindegyike (nem feltétlenül egy sorban, hanem akárhol), akkor az alábbi a megoldás (rekurzívan kell nekem):

ÉS kapcsolattal:


agrep -ir "hello;szia" .

VAGY kapcsolattal:


egrep -ir "hello|szia" .

Azért ez ennyire nem egyszerű. Nekem például 'természetesen' csak akkor működik, ha az alapértelmezett rekordelválasztó (újsor) helyett megadok egy másikat (és a tesztben pl. ezt adtam meg: -d "^$" - azaz üres sor), és ezen a rekordon belül volt.

Szóval én mégis inkább valami ilyet választanék:


grep -l egyikminta `grep -l masikminta vizsgalando fajlok listaja` 

Eredménye azon fájlok neve, amiben mind a kettő megtalálható, tök mindegy, hogy hol.

Ez az! Pontosan valami ilyen megoldást kerestem, köszi. Hasonlón gondolkodtam én is, hogy 1x szűrni, és a fájlneveket átadni a második szűréshez, csak nem tudtam hogyan ;) Az ilyen megoldást szeretem, nem kell külön progi, mindenhol jó és relatíve egyszerű :)

Beírom ahogy nekem kell, rekurzívan stb.:


grep -irl minta1 `grep -irl minta2 .`

for files in `grep -l minta fileok*` ; do
grep -l masodikminta $files
done