2009-08-31 7 views
20

ignorer que j'utilise habituellement le pipeline suivant à grep pour une chaîne de recherche particulière et ignorer encore certains autres modèles:Recherche multiple grep/modèles

grep -Ri 64 src/install/ | grep -v \.svn | grep -v "file"| grep -v "2\.5" | grep -v "2\.6" 

peut-il être réalisé de manière succincte? J'utilise GNU grep 2.5.3.

+0

L'utilité de la réponse dépend également des chaînes sont susceptibles de changement. Si la seule chaîne qui change est "64" pourquoi ne créez-vous pas une fonction ou un script shell pour cela? – tripleee

Répondre

25

Juste tuyau votre sortie non filtrée en une seule instance de grep et utiliser une expression rationnelle de déclarer ce que vous voulez ignorer:

grep -Ri 64 src/install/ | grep -v -E '(\.svn|file|2\.5|2\.6)' 

Edit: Pour rechercher plusieurs fichiers peut-être essayer

find ./src/install -type f -print |\ 
    grep -v -E '(\.svn|file|2\.5|2\.6)' | xargs grep -i 64 

Editer: Ooh. J'ai oublié d'ajouter le truc simple pour arrêter une utilisation cringeable de plusieurs instances de grep, à savoir

ps -ef | grep something | grep -v grep 

Remplacement qui avec

ps -ef | grep "[s]omething" 

supprime la nécessité du second grep.

+2

Les parenthèses doivent être entre guillemets .. sinon bash se plaint: erreur de syntaxe près du jeton inattendu '(' –

+0

Mis à jour! Merci –

+0

Il y a un bogue dans votre solution et l'exemple dans ma question: le second grep correspondra à la ligne réelle * * le nom de fichier qui apparaît dans la sortie du premier grep Ceci est bon pour ignorer '.svn' .. mais pas d'autres modèles –

1

Vous voulez peut-être utiliser ack-grep qui permet d'exclure aussi avec perl regexp et d'éviter tous les répertoires VC, idéal pour grepping code source.

+0

Merci pour le pointeur; pour l'arborescence des sources purement Python, j'utilise actuellement 'py.lookup' depuis http://pylib.org/ –

2

vous pouvez utiliser awk au lieu de grep

awk '/64/&&!/(\.svn|file|2\.[56])/' file 
+0

Cela imprime succinctement les lignes d'un seul fichier, mais ne parvient pas à faire la récursion depuis le premier grep. Mais il peut être utilisé avec succès en combinaison avec le suggéré «trouver | solution xargs'. Vous devriez également ajouter l'impression du nom de fichier avant la correspondance pour émuler complètement le comportement de grep. – tripleee

7

Utilisez l'option -e pour spécifier plusieurs modèles:

grep -Ri 64 src/install/ | grep -v -e '\.svn' -e file -e '2\.5' -e '2\.6' 

Vous pourriez être également intéressé par le drapeau -F, ce qui indique que les modèles sont fixés chaînes au lieu d'expressions régulières. Maintenant, vous ne devez pas échapper à la dot:

grep -Ri 64 src/install/ | grep -vF -e .svn -e file -e 2.5 -e 2.6 

Je remarque que vous étiez Grepping sur « svn ». Vous voulez probablement ignorer les répertoires nommés ".svn" dans votre grep récursif initial. Si je je referais ce lieu à votre place,:

grep -Ri 64 src/install/ --exclude-dir .svn | grep -vF -e file -e 2.5 -e 2.6 
0

Le script suivant supprime tous les fichiers sauf une liste de fichiers:

echo cleanup_all [email protected] 


if [[ $# -eq 0 ]]; then 
FILES=`find . -type f` 
else 
EXCLUDE_FILES_EXP="(" 
for EXCLUDED_FILE in [email protected] 
do 
    EXCLUDE_FILES_EXP="$EXCLUDE_FILES_EXP./$EXCLUDED_FILE|" 
done 
# strip last char 
EXCLUDE_FILES_EXP="${EXCLUDE_FILES_EXP%?}" 
EXCLUDE_FILES_EXP="$EXCLUDE_FILES_EXP)" 
echo exluded files expression : $EXCLUDE_FILES_EXP 

    FILES=`find . -type f | egrep -v $EXCLUDE_FILES_EXP` 
fi 

echo removing $FILES 

for FILE in $FILES 
do 
    echo "cleanup: removing file $FILE" 
    rm $FILE 
done