Actualmente escribí un programa para tomar la desviación estándar de un solo conjunto de datos. Tengo más de 200 carpetas, cada una con su propio conjunto de datos. Estoy tratando de escribir un archivo bash que ejecutará este programa para todas las carpetas (al tiempo que genera toda la desviación estándar en un archivo maestro según lo dictado en python).

Hasta ahora tengo:

#!/bin/bash

for D in SAND; do python sample.py
  [ -d "$D" -a -x "$D/all" ] && "$D/all"
done

Nota: SAND es mi directorio.

Pero esto no funciona. Por favor ayuda.

Además, cuando pruebo otros ejemplos y los ejecuto, sigo teniendo el error:

Traceback (most recent call last):
  File "sample.py", line 1, in <module>
    f=open("default")
IOError: [Errno 2] No such file or directory: 'default'

A pesar de que sí tengo el archivo de datos "predeterminado" en las carpetas.

0
Domovoi 3 sep. 2014 a las 06:47

2 respuestas

La mejor respuesta

Lo siguiente supone que SAND es el nombre literal de su directorio.

Primera opción: usar un bucle.

for d in SAND/*/all; do
  python sample.py "$d"
done

... o, si necesita cambiar al directorio que se encuentra ...

orig_dir=$PWD
for d in SAND/*/all; do
  (cd "$d/.." && exec python "$orig_dir/sample.py" all)
done

Segunda opción: usar find.

Sugeriría buscar directamente los objetivos llamados all:

find SAND -name all -exec python sample.py '{}' '+'

Alternativamente, con POSIX find, puede hacer que find invoque un shell para realizar más lógica:

find SAND -type d -exec bash -c \
  'for d; do [[ -d "$d/all" ]] && python sample.py "$d/all"; done' _ '{}' +

Si SAND es un nombre de variable, no un directorio literal, cambie SAND en el anterior a "$SAND", con las comillas (e, idealmente, en minúsculas, por convención, solo las variables de entorno y las variables integradas de shell deben ser mayúsculas para evitar conflictos de espacio de nombres).

2
Charles Duffy 3 sep. 2014 a las 03:03

Alternativamente, puede omitir bash por completo y modificar su script Python. os.walk() le permite visitar cada directorio a su vez:

import os,sys

for arg in sys.argv[1:] or ['.']:
  for dirpath, _, filenames in os.walk(arg):
    for filename in filenames:
      if filename == 'all':
        all_file = os.path.join(dirpath, filename)
        default_file = os.path.join(dirpath, 'default')
        # ... whatever you do with SAND/foo/all
        # foo = open(all_file)
        # std_dev = bar(foo)
        # ... I'll just print them
        print all_file, default_file
1
Robᵩ 3 sep. 2014 a las 03:16