Cómo hacer un bucle sobre los archivos en el directorio y cambiar la ruta y añadir el sufijo al nombre del archivo

Necesito escribir un script que inicie mi programa con diferentes argumentos, pero soy nuevo en Bash. Comienzo mi programa con:

./MiPrograma.exe Datos/data1.txt [Logs/data1_Log.txt].

Aquí está el pseudocódigo de lo que quiero hacer:

for each filename in /Data do
  for int i = 0, i = 3, i++
    ./MyProgram.exe Data/filename.txt Logs/filename_Log{i}.txt
  end for
end for

Así que I'm realmente desconcertado cómo crear segundo argumento de la primera, por lo que parece dataABCD_Log1.txt y empezar mi programa.

Solución

Un par de apuntes: cuando usas Datos/data1.txt como argumento, ¿debería ser realmente /Data/data1.txt (con una barra al principio)? Además, ¿el bucle externo debe buscar sólo los archivos .txt, o todos los archivos de /Data? Aquí está la respuesta, asumiendo que /Data/data1.txt y los archivos .txt solamente:


#!/bin/bash
for filename in /Data/*.txt; do
    for ((i=0; i `file`)

Si necesita ejecutar MiPrograma con `Datos/archivo.txt` en lugar de `/Datos/archivo.txt`, utilice `"${filename#/}"` para eliminar la barra diagonal inicial. Por otra parte, si realmente es `Data` y no `/Data` lo que quiere escanear, sólo tiene que utilizar `for filename in Data/*.txt`.
Comentarios (7)

Perdón por necromar el hilo, pero siempre que se itera sobre archivos mediante globbing, es una buena práctica evitar el caso de esquina en el que el glob no coincide (lo que hace que la variable del bucle se expanda a la propia cadena del patrón glob (que no coincide)).

Por ejemplo:

for filename in Data/*.txt; do
    [ -e "$filename" ] || continue
    # ... rest of the loop body
done

Referencia: Bash Pitfalls

Comentarios (9)
for file in Data/*.txt
do
    for ((i = 0; i < 3; i++))
    do
        name=${file##*/}
        base=${name%.txt}
        ./MyProgram.exe "$file" Logs/"${base}_Log$i.txt"
    done
done

La sustitución nombre=${archivo##*/} (expansión de parámetros del shell) elimina el nombre de la ruta principal hasta el último /.

La sustitución base=${nombre%.txt} elimina el final de .txt. Es un poco más complicado si las extensiones pueden variar.

Comentarios (2)