Найти - Пользователи
Полная версия: выполнить команду над последовательностью файлов
Начало » Python для новичков » выполнить команду над последовательностью файлов
1
aleshgo
Доброе время суток,
Подскажите пожалуйста есть ли готовая библиотека делающая следующие:

Найти пути файлов в заданном каталоге с определенным расширением и передеть внешней программе как параметр, также этой программе надо передать эти пути измененные по шаблону

Например:
есть каталог /input:
со структурой:
/input/index.haml
/input/base/bar.haml
/input/base/too.haml

я передал бы этой функции
(path=' /input', file='*.haml', command_exec='haml', command_arg='{abspath}/{name}.{ext} /out/{relpath}/{name}-{ext}-test.html')

и она вызвала бы мне внешную программу:

haml /input/index.haml /out/index-haml-test.html
haml /input/base/bar.haml /out/base/bar-haml-test.html
haml /input/base/too.haml /out/base/too-haml-test.html

Заранее благодарен
Alen
aleshgo
Найти пути файлов в заданном каталоге с определенным расширением и передеть внешней программе как параметр, также этой программе надо передать эти пути измененные по шаблону

import glob
import subprocess
dir = '/input'
list_files =[]
subdir = ('/', '/base/')
for s in subdir:
    list_files.extend(glob.glob(dir + s + "*.haml"))
for ex in list_files:
    out = subprocess.Popen(['haml', ex, ex.replace('input', 'out')], stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
fedorch
Посмотрите в сторону стандартной функции os.walk() она возвращает список всех файлов в каталоге и его подкаталогах.

for dirname, dirnames, filenames in os.walk("путь с которого начинаем обход"):
    for file in filenames:
        # здесь анализируем имя файла file и решаем что с ним делать
        # полный путь к каждому файлу можно получить os.path.join(dirname, file)
aleshgo
Alen, fedorch спасибо за ответы, но это не совсем то что я имел ввиду (я не совсем нуб), я наверно не совсем ясно выразился, я просто не знаю как правильно это назвать.

Я набрасал, что я имел ввиду, может кто знает готовую библиотеку делающее что то подобное что бы я не изобритал велосипед:
# -*- coding: utf-8 -*-
#
# copyright: (c) 2014 by George A Levchenko <george.a.levchenko@gmail.com>.
#
# Утилиты для работы с файловой системой
import os
import subprocess
from fnmatch import fnmatch
from collections import namedtuple
File = namedtuple('File', ['name', 'abspath', 'relpath'])
def find(path, mask='*'):
  """ Поиск файлов с заданной маской """
  # Позвращает:
  # имя файла, абсолютный путь к файлу, относительный путь
  filelist = []
  for dirpath, dirnames, filenames in os.walk(path):
    for file in filenames:
      if fnmatch(file, mask):
        relpath = os.path.relpath(dirpath, path)
        if relpath == '.':
          relpath = ''
        filelist.append(File(file, dirpath, relpath))
  return filelist
def mkdir(dir):
  # If the directory doesn't exist
  if not os.path.exists(dir):
    # Create it
    os.mkdir(dir)
def command(command_exec, command_arg, file):
  """
  Доступные переменные для command_arg:
    {fullpath} - {abspath}{name}.{ext}
    {abspath} - обсолютный путь к файлу
    {relpath} - отноcительный путь
    {name} - имя файла
    {ext} - расширения файла
  """
  abspath = file.abspath
  relpath = file.relpath
  name, ext = os.path.splitext(file.name)
  fullpath = os.path.join(abspath, file.name)
  command_arg = command_arg.format(fullpath=fullpath, abspath=abspath, relpath=relpath, name=name, ext=ext[1:])
  command_str = command_exec.split() + command_arg.split()
  # print (command_str)
  subprocess.call(command_str)
if __name__ == '__main__':
  basedir = os.path.abspath(os.path.dirname(__file__))
  backup_dir = os.path.join(basedir, 'test/backup')
  input_path = os.path.join(basedir, 'test/folder')
  for file in find(input_path, '*.fde'):
    mkdir(os.path.join(backup_dir, file.relpath))
    command('cp', '{fullpath} %s/{relpath}/{name}-{ext}.txt ' % backup_dir, file)
doza_and
Думаю в таком виде как вы написали библиотечной функции нет. Ваша задача включает 3 подзадачи.
Поиск файлов, преобразование полученного пути и выполнение команды. Комбинаций из 3 элементов очень много, ваша command решает очень узкоспециализированную задачу и не будет полезна остальным как библиотечная функция (хотя может быть полезна вам в данном случае).
Питонистый путь скорее будет выглядеть так:
for name in some_finder():
     cmdl = Transformer(name)
     subprocess.check_call(cmdl)

А в библиотеке будет some_finder и Transformer
В питоне на мой взгляд есть неудобные места.
Неудобно разбивать пути при помощи os.path.split
os.walk тоже не всегда удобен.
Поэтому иногда пользуюсь велосипедом
def PathFind(pattr, root="."):
    u"""аналог find из bash"""
    for di, dl, fl in os.walk(root):
        for f in glob.fnmatch.filter(fl, pattr):
            yield os.path.join(di, f)
def PathFindDir(pattr, root="."):
    u"""аналог find из bash"""
    for di, dl, fl in os.walk(root):
        for f in glob.fnmatch.filter(dl, pattr):
            yield os.path.join(di, f)

Для резервного копирования можно использовать архиваторы. Ваш пример они покрывают.
7z a -r backup_file.7z *.ext1 *.ext2 .... 

А то что вы уродуете имена файлов мне совсем не нравится. Зачем это делать?

Т.е. небольшое изменение постановки задачи приведет вас на проторенную дорожку и задача решится в одну строку.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB