Grep za to i nie za to w pliku?

0

Jak mogę grep dla plików w strukturze katalogów, które mają ten tekst

addDesignControlChangeNotification

ale brakuje tego tekstu

removeDesignControlChangeNotification

Dzięki!

Uwaga: Mam na myśli katalog, w którym uruchamiany jest skrypt i wszystkie podkatalogi.

Dan Rosenstark
źródło
Hmm, w głównym katalogu lub głównym katalogu i podkatalogach?
Rich Homolka
Mam na myśli katalog, w którym uruchamiamy skrypt i wszystkie podkatalogi. Przepraszam, że wcześniej nie było to jasne.
Dan Rosenstark

Odpowiedzi:

1

Oto jeden, który jest luźno oparty na Richie Homolki odpowiedź , ale działa na drzewach katalogów:

find . -type f  -exec grep -l addDesignControlChangeNotification {} \; | 
 while IFS= read -r file; do 
   grep -q removeDesignControlChangeNotification "$file" > /dev/null ; 
   [ $? -ne 0 ] && echo $file; 
 done

Wszelkie zwrócone pliki będą zawierać addDesignControlChangeNotification ale nie removeDesignControlChangeNotification.

WYJAŚNIENIE:

  • find . -type f -exec grep -l foo {} \;: Spowoduje to wydrukowanie wszystkich plików w dowolnym podkatalogu bieżącego katalogu zawierającego ciąg foo. The -l Flaga powoduje, że grep drukuje tylko nazwy pasujących plików.

  • while read file : iteruje po każdym pliku znalezionym powyżej, zapisując jego nazwę w zmiennej $file.

  • grep -q bar "$file" > /dev/null : to polecenie szuka ciągu bar w każdym z zawartych w nim plików foo.

  • [ $? -ne 0 ] && echo $file; : Jeśli wartość zwracana ( $? ) z grep komenda miała wartość 0 (tzn. jeśli łańcucha nie było w pliku), wydrukuj nazwę pliku.

terdon
źródło
Niesamowite, używam find . -name '*.m' -type f -exec grep -l addDesignControlChangeNotification {}... które dodałem, ponieważ nie wspomniałem o tym w pytaniu;) Dzięki!
Dan Rosenstark
2

to powinno działać:

FIRST=addDesignControlChangeNotification
SECOND=removeDesignControlChangeNotification
grep -l $FIRST * | while IFS= read -r FILE
do
    grep $SECOND "$FILE" &> /dev/null
    if [ $? -ne 0 ]
    then
        echo "File $FILE has $FIRST but not $SECOND"
    fi
done
Rich Homolka
źródło
Wygląda świetnie, ale dostaję „Jest katalog” zamiast faktycznie wchodzić do tych katalogów. Masz jakiś pomysł, co się stało? Dziękuję +1!
Dan Rosenstark
@Yar, możesz dodać -r do pierwszego grep polecenie, jeśli chcesz rekursować katalogi. Możesz też użyć mojej odpowiedzi;).
terdon
0

Jedna linijka:

comm -2 -3 <(grep -rl addDesignControlChangeNotification     . | sort ) \
           <(grep -rl removeDesignControlChangeNotification  . | sort )

grep -r jest rekurencyjnym grepem, <() jest zastąpienie procesu , i comm pokazuje linie, które para (posortowanych) plików ma / nie mają wspólnego. W tym przypadku chcemy tylko wyjście kolumny 1: linie w pierwszym pliku (gdzie „plik” jest naprawdę wyjściem grep), które nie znajdują się w drugim.

mr.spuratic
źródło