2009-08-31 14 views
20

por lo general utilizan la siguiente tubería a grep para una cadena de búsqueda en particular y sin embargo ignorar ciertos otros patrones:múltiple de búsqueda grep patrones/ignore

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

se puede lograr esto de manera sucinta? Estoy usando GNU grep 2.5.3.

+0

La utilidad de la respuesta depende también de qué cadenas son probablemente cambio. Si la única cadena que cambia es "64", ¿por qué no creas una función o script de shell para esto? – tripleee

Respuesta

25

Sólo tubo de la salida no filtrada en una sola instancia de grep y usar una expresión regular extendida para declarar lo que desea ignorar:

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

Editar: buscar varios archivos quizás prueba

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

Editar: Ooh. Se me olvidó añadir el simple truco para detener un uso cringeable de varias instancias grep, a saber

ps -ef | grep something | grep -v grep 

Sustitución de que con

ps -ef | grep "[s]omething" 

elimina la necesidad de la segunda grep.

+2

Los paréntesis se deben citar ... de lo contrario bash se queja: error de sintaxis cerca del token inesperado '(' –

+0

¡Actualizado! Gracias. –

+0

Hay un error en su solución y el ejemplo en mi pregunta: el segundo grep coincidirá con la línea real * y * el nombre de archivo que aparece en la salida del primer grep. Esto es bueno para ignorar '.svn' .. pero no en otros patrones. –

1

Es posible que desee utilizar ack-grep que permiten excluir también con perl regexp y evitar todos los directorios de VC, ideal para grepping código fuente.

+0

Gracias por el puntero; para el árbol fuente puramente de Python, actualmente uso 'py.lookup' de http://pylib.org/ –

2

puede usar awk en lugar de grep

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

Esto imprime líneas de un solo archivo, pero no puede hacer la recursión desde el primer grep. Pero se puede usar de manera fructífera en combinación con el 'hallazgo' sugerido xargs' solución. También debería agregarse la impresión del nombre del archivo antes de la coincidencia para emular completamente el comportamiento de grep. – tripleee

7

Utilice la opción -e para especificar varios patrones:

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

Usted también puede estar interesado en la bandera -F, lo que indica que los patrones son fijos cadenas en lugar de expresiones regulares. Ahora usted no tiene que escapar del punto:

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

me di cuenta de que estabas grepping a cabo ".svn". Probablemente quiera omitir cualquier directorio llamado ".svn" en su grep recursivo inicial. Si yo fuera usted, me gustaría hacer esto en su lugar:

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

La siguiente secuencia de comandos se eliminarán todos los archivos excepto una lista de archivos:

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 
Cuestiones relacionadas