para - recorrer directorio bash
¿Cómo iterar sobre archivos en un directorio con Bash? (5)
Algo que uso para evitar tener líneas o cheques adicionales:
#!/bin/bash
for filename in $(find /Data/*.txt 2> /dev/null); do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done
La idea es ejecutar el hallazgo en una subshell y enviar errores a / dev / null, para que nunca pase un error sobre los archivos que faltan.
Necesito escribir un script que inicie mi programa con diferentes argumentos, pero soy nuevo en Bash. Comienzo mi programa de esta manera:
./MyProgram.exe Data/data1.txt [Logs/data1_Log.txt]
.
Aquí está el pseudocódigo para 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 if
end for
Así que estoy realmente sorprendido de cómo crear un segundo argumento a partir del primero, por lo que parece dataABCD_Log1.txt y comenzar mi programa. Se aprecia mucho la ayuda.
PD: Sé que hay preguntas similares, pero no encontré nada al crear mi nombre de archivo de registro.
Disculpe por nigromanciar el hilo, pero siempre que realice una iteración sobre los archivos mediante el uso de globos, es una buena práctica evitar el caso de la esquina donde el globo no coincide (lo que hace que la variable de bucle se expanda a la propia cadena de patrón del globo (no coincidente)).
Por ejemplo:
for filename in Data/*.txt; do
[ -e "$filename" ] || continue
# ... rest of the loop body
done
Referencia: Bash Pitfalls
Parece que estás intentando ejecutar un archivo de Windows (.exe) Seguramente deberías estar usando powershell. De todos modos, en un shell bash de Linux bastará con una sola línea.
[/home/$] for filename in `ls /Data/*.txt`; do for i in {0..3}; do ./MyProgam.exe Data/filename Logs/$filename_log$i.txt; done done
O en una fiesta
#!/bin/bash
for filename in `ls /Data/*.txt`;
do
for i in {0..3};
do ./MyProgam.exe Data/filename.txt Logs/$filename_log$i.txt;
done
done
Un par de notas primero: cuando usa Data/data1.txt
como argumento, ¿debería ser realmente /Data/data1.txt
(con una barra diagonal)? Además, ¿debería el bucle externo explorar solo archivos .txt, o todos los archivos en / Datos? Aquí hay una respuesta, asumiendo solo los archivos /Data/data1.txt
y .txt:
#!/bin/bash
for filename in /Data/*.txt; do
for ((i=0; i<=3; i++)); do
./MyProgram.exe "$filename" "Logs/$(basename "$filename" .txt)_Log$i.txt"
done
done
Notas:
-
/Data/*.txt
expande a las rutas de los archivos de texto en / Data ( incluida la / Data / part) -
$( ... )
ejecuta un comando de shell e inserta su salida en ese punto en la línea de comandos -
basename somepath .txt
genera la parte base de somepath, con .txt eliminado del final (por ejemplo,/Data/file.txt
->file
)
Si necesitaba ejecutar MyProgram con Data/file.txt
lugar de /Data/file.txt
, use "${filename#/}"
para eliminar la barra diagonal inicial. Por otro lado, si realmente no es Data
/Data
que quiere escanear, solo use el for filename in Data/*.txt
.
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 name=${file##*/}
( expansión de parámetros de shell ) elimina el nombre de ruta principal hasta el último /
.
La base=${name%.txt}
sustitución elimina el .txt
final. Es un poco más complicado si las extensiones pueden variar.