Tengo una carpeta con muchos archivos (xyz1, xyz2, hasta xyz5025) y necesito ejecutar un script en cada uno de ellos, obteniendo xyz1.faa, xyz2.faa, etc. como salidas.
El comando para un solo archivo es:
./transeq xyz1 xyz1.faa -table 11
¿Hay alguna manera de hacer eso automáticamente? Tal vez un combo para hacer?

for file in xyz*; do ./transeq "$file" "${file}.faa" -table 11; done. Escribo este tipo de cosas todo el tiempo. Y si desea verificar que los nombres de archivo, etc., se expanden de la manera que desea, simplemente coloque unechoderecho después dedola primera vez, y luego regrese a su historial de shell y elimínelo la segunda vez."$file".faaes un poco más fácil de escribir como parte de una línea interactiva y segura, ya.faaque no contiene metacaracteres de shell que necesitan ser citados.xyz*globo también recogerá archivos .faa. Para bash, ejecuteshopt -s extglob( referencia ), luego usefor file in xyz!(*.faa) ...para excluir que los archivos .faa se envíen a través del bucle.Si instala GNU Parallel , puede hacerlo en paralelo de esta manera:
Si su programa consume mucha CPU, debería acelerarse un poco.
fuente
Puede hacer algo como esto en una
bashlínea de comando:Estamos generando los enteros del 1 al 5025, uno / línea, luego los alimentamos uno por uno a xargs, que encapsula el entero en
{}y luego lo trasplanta a la línea de comando ./transeq de manera apropiada.Si no tiene la función de expansión de llaves,
{n..m}puede invocar lasequtilidad para generar esos números.O bien, siempre puede emular la generación numérica a través de:
fuente
for i in {1..5025}; do ./transeq "xyz$i" "xyz$i".faa -table 11; donees mucho más fácil pensar y escribir. Si desea que imprima comandos antes de ejecutarlos, useset -x.for i in{1..5025}para lograr exactamente el mismo resultado que el tuyo. También podría escribirfor ((i=1 ; i<=5025 ; i++)); do ./transeq "xyz$i" "xyz$i".faa -table 11; doneen bash, pero generalmente uso la{a..b}sintaxis de rango porque es más rápido de escribir.Usando find, útil cuando sus archivos están dispersos dentro de directorios
fuente
Suponiendo que tiene más de un núcleo, y cada invocación puede ejecutarse independientemente del resto, obtendrá una aceleración considerable con ejecuciones paralelas.
Una forma relativamente simple de hacerlo es a través del
-Pparámetro dexargs, por ejemplo, si tiene 4 núcleos:El
-n 1le dicexargsque elija solo un argumento de la lista para cada invocación (por defecto pasaría mucho) , y-P 4le dice que genere 4 procesos al mismo tiempo: cuando uno muere, se genera uno nuevo.En mi humilde opinión, no es necesario instalar GNU en paralelo para este caso simple - es
xargssuficiente.fuente
Puedes usar
xargls | xargs -L 1 -d '\n' your-desired-command-L 1causa pasar 1 artículo a la vez-d '\n'la salida delsmake se divide en función de la nueva línea.fuente