Acelera la secuencia de commands bash que usa varios commands de búsqueda

Tengo un script bash para agregar algunos files de un proyecto a git y luego sincronizar esa twig, ya que la cantidad de files ha aumentado. He notado que el script se ha vuelto mucho más lento, así que quiero averiguar si lo estoy haciendo forma correcta

Esta es la sección de la secuencia de commands donde se agregan los files:

echo "Adding files..." find . -name '*.js' -exec git add {} \; find . -name '*.html' -exec git add {} \; find . -name '*.css' -exec git add {} \; find . -name '*.py' -exec git add {} \; find . -name '*.txt' -exec git add {} \; find . -name '*.jpg' -exec git add {} \; find . -name '*.sh' -exec git add {} \; echo "Commit" git commit -m "'$1'" 

No estoy seguro de si hacer una sola llamada sería más rápido que tener todos estos commands separados, pero lo hice de esta manera, por lo que era más simple eliminar algunos types de files o agregar otros nuevos.

Realmente agradecería cualquier sugerencia para hacer esto más eficiente, usar los commands de una manera diferente o usar diferentes commands es una respuesta completamente aceptable.

 find . \( -name '*.js' -o \ -name '*.html' -o \ -name '*.css' -o \ -name '*.py' -o \ -name '*.txt' -o \ -name '*.jpg' -o \ -name '*.sh' \) -exec git add {} + 

Esto significa que solo escanea la estructura del directory una vez, que es la forma principal de acelerar 'múltiples find '; usted reemplaza 'múltiple' por 'uno'. El + es un complemento de POSIX 2008 para find pero lo hace actuar más como xargs por sí mismo. Si no está disponible para usted, considere usar -print y xargs (o, si es probable que tenga espacios en blanco en los nombres y tenga GNU find y xargs , entonces -print0 y -print0 xargs -0 , pero si los tiene, usted (probablemente, pero vea el comentario) también tiene la notación + ).

Si git admite agregar múltiples files en un command, lo más simple que puede hacer es usar el sufijo + para -exec :

 find . -name '*.js' -exec git add {} \+ 

Esto reúne una gran cantidad de files y los pasa todos al command en una línea de command.

Entonces, ¿qué se ejecutará es:

 git add a.js b.js c.js d.js 

en lugar de

 git add a.js git add b.js git add c.js git add d.js 

Si está procesando cientos o miles de files, esto hará una gran diferencia en el time de ejecución.

Para combinar todos los patrones de files en un solo command de find , use el operador "or" de find:

 find . \( -name '*.js' -o \ -name '*.html' -o \ -name '*.css' -o \ -name '*.py' -o \ -name '*.txt' -o \ -name '*.jpg' -o \ -name '*.sh' \) -exec git add {} + 

El \ before ( y ) es necesario para protegerlos de su significado especial de shell. También podría usar citas en su lugar: '(' , ')' .

find tiene algunas opciones complicadas y uno tiene que tomarse un poco la molestia de aprenderlas y familiarizarse con ellas, pero me he ahorrado mucho esfuerzo a lo largo de los años al poder sacar un complicado command de find lugar de luchar con filtrando nombres de file a través de grep y awk, etc.

Uno de mis patrones favoritos actuales para escanear a través de un proyecto maven / subversion java mientras se ignoran los files poco interesantes es:

 find . \( \( \( -iname .svn -o -iname target -o -iname classes \) -type d -prune -false \) -o \( <your filter expression> \) \) -exec grep -li xxx {} + 

Si tu

  • tener Bash 4
  • están buscando solo por nombre (no por otros criterios)

puedes usar esto también:

 shopt -s globstar git add **/*.{js,html,css,py,txt,jpg,sh} 

Notas:

  1. La expansión de llaves se ejecuta antes de la expansión del nombre de file, por lo que esto es equivalente a escribir

     git add **/*.js **/*.html etc... 
  2. globstar permite la expansión recursiva del nombre de file a través de la palabra key ** .

El command git add puede hacer esto sin ningún otro script de shell.

 git add -- '*.js' '*.html' '*.css' ... 

Esto puede ser más rápido:

 F='\.js$|\.html$|\.css$|\.py$|\.txt$|\.jpg$|\.sh$' find . | egrep $F | xargs git add 

o alguna variación de este si esperas espacios u otros caracteres especiales en los nombres de file.