script recorrer para directorio comandos comando archivos bash for-loop filenames

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.