linea hay demasiados comandos argumentos linux bash grep

linux - hay - bash demasiados argumentos



¿Cómo puedo grep mientras evito ''Demasiados argumentos'' (5)

Esta pregunta ya tiene una respuesta aquí:

Estaba tratando de limpiar algunos correos electrónicos no deseados y encontré un problema. La cantidad de archivos en la cola era tan grande que mi comando habitual no podía procesar. Me daría un error sobre demasiados argumentos.

Yo suelo hacer esto

grep -i [email protected] 1US* | awk -F: ''{print $1}'' | xargs rm

1US * puede ser cualquier cosa entre 1US [a-zA-Z]. Lo único que podía hacer era ejecutar este horrible artilugio. Es un archivo, con 1USa, 1USA, 1USb, etc., a través de todo el alfabeto. Sé que tiene que ser una forma de ejecutar esto de manera más eficiente.

grep -s $SPAMMER /var/mailcleaner/spool/exim_stage1/input/1USa* | awk -F: ''{print $1}'' | xargs rm grep -s $SPAMMER /var/mailcleaner/spool/exim_stage1/input/1USA* | awk -F: ''{print $1}'' | xargs rm


Usar xargs es más eficiente que usar "find ... -exec grep" porque tienes menos creaciones de procesos, etc.

Una forma de hacerlo sería:

ls 1US* | xargs grep -i [email protected] | awk -F: ''{print $1}'' | xargs rm

Pero más fácil sería:

find . -iname "1US*" -exec rm {} /;


Ejecuta varias instancias de grep. En lugar de

grep -i [email protected] 1US* | awk ''{...}'' | xargs rm

hacer

(for i in 1US*; do grep -li user@domain "$i"; done) | xargs rm

Tenga en cuenta el indicador -l, ya que solo queremos el nombre de archivo de la coincidencia. Esto acelerará grep (finalizará en la primera coincidencia) y hará que su script awk no sea necesario. Esto podría mejorarse verificando el estado de retorno de grep y llamando a rm, sin usar xargs (xargs es muy frágil, IMO). Te daré la mejor versión si lo preguntas.

Espero eso ayude.


El argumento -exec para find es útil aquí, lo he usado yo mismo en situaciones similares.

P.ej

# List the files that match find /path/to/input/ -type f -exec grep -qiF [email protected] /{/} /; -print # Once you''re sure you''ve got it right find /path/to/input/ -type f -exec grep -qiF [email protected] /{/} /; -delete


Usa find y un loop en lugar de xargs .

find . -name ''1US*'' | / while read x; do grep -iq user@domain "$x" && rm "$x"; done

Esto utiliza pipes y loops en lugar de argumentos (tanto para grep como rm ) y evita problemas relacionados con los límites en los argumentos.


puede usar find para encontrar todos los archivos cuyo nombre comience con el patrón ''1US''. Luego puede canalizar la salida a xargs, que se ocupará de que la lista de argumentos no crezca demasiado y maneje la llamada grep. Tenga en cuenta que he usado un nullbyte para separar nombres de archivo para xargs. Esto evita problemas con nombres de archivos problemáticos . ;)

find -maxdepth 1 -name ''1US*'' -printf ''%f/0'' | xargs -0 grep -u user@domain | awk ...