Estoy buscando archivos basados en una expresión regular, y luego intento buscar contenido en esos archivos. Entonces, por ejemplo, tengo algo como
#Find all C++ files that match a certain pattern and then search them
find . -name "*.cpp" | grep "<name regex>" | xargs grep "<content regex>"
El problema con el que me encuentro es que algunos de los caminos tienen espacios en ellos, lo que confunde xargs
. Sé que si solo estuviera usando find
, podría usar el -print0
argumento (junto con el -0
argumento encendido xargs
) para evitar que los xargs traten los espacios como delimitadores. ¿Hay algo similar con grep
?
¿O estoy abordando este problema por completo de manera incorrecta? Ingenuamente, find
a grep
que xargs grep
tiene sentido para mí, pero estoy abierto a otros enfoques que permitan obtener los mismos resultados.
xargs
uso del-i
parámetro, a lacat sample.txt | grep "pat t ern" | xargs -i grep "{}"
- las llaves indican dónde colocar el argumento. El manual me dice que-i
está en desuso, por-I
lo que quizás valga la pena echarle un vistazo también.Respuestas:
Use algo como esto quizás (si gnu grep).
hombre grep
Consulte también las opciones para delimitadores nulos.
fuente
grep -r include='*.cpp'
es un globo de shell, y también está alineado con las funciones w /find . -name '*.cpp' -exec grep -e 'content_pattern' -- {} \;
not w /find . -name '*.cpp' | grep 'name_pattern' | xargs grep 'content_pattern'
Si tienes que saltar muchos aros, la eficiencia de los xargs se pierde de todos modos. Aquí hay una solución cruda:
Cada vez que me encuentro con problemas con espacios en los nombres de archivo, la respuesta son comillas dobles en una variable.
fuente
Use
find
para hacer todo el filtrado de nombres de archivo. Más bien quehacer
Si quieres hacer algo un poco más complicado, como
tu puedes hacer
Tenga en cuenta que estos deberían funcionar incluso para archivos con nuevas líneas en sus nombres.
Y, si necesita el poder de expresiones regulares completas, puede usar
-regex
.fuente
Esto debería funcionar incluso sin las herramientas GNU:
La
perl
llamada reemplaza los saltos de línea con caracteres nulos, lo que permitiráxargs -0
interpretar la entrada por línea en lugar de por espacio en blanco.Con GNU, puede eliminar la
perl
llamada y cambiarxargs -0 …
axargs -d "\n" …
¿No tienes
perl
o GNU? Intenta en suawk '{printf "%s%c", $0, 0}'
lugar.fuente
xargs -d "\n"
. Es un hecho muy inusual, pero si no tiene control de los datos y le preocupa que sea un riesgo de seguridad, tenga cuidado con las expectativas de salida.