Эквивалент Python для поиска -exec

Я пытаюсь запустить эту команду BASH в Попене:

find /tmp/mount -type f -name "*.rpmsave" -exec rm -f {} \;

Но каждый раз, когда я получаю: "find: отсутствует аргумент`-exec'\n"в stderr.

Каким будет Python-эквивалент этого?

Мой наивный подход был бы:

for (root,files,subdirs) in os.walk('/tmp/mount'):
    for file in files:
        if '.rpmsave' in file:
            os.remove(file)

наверняка есть лучший, более питонный способ сделать это?

3 ответа

Решение

У вас есть два вопроса здесь - во-первых, почему ваш Popen строительство не работает, а во-вторых, как использовать os.walk должным образом. Нед ответил на второй, поэтому я расскажу на первый: вы должны знать, что оболочка может сбежать. \; сбежал ; так как обычно ; будет интерпретирован Bash как разделяющий две команды оболочки, и не будет передан find, (В некоторых других оболочках {} также должен быть экранирован.)

Но с Popen вы вообще не хотите использовать оболочку, если можете ее избежать. Итак, это должно работать:

import subprocess

subprocess.Popen(('find', '/tmp/mount', '-type', 'f',
                  '-name', '*.rpmsave', '-exec', 'rm', '-f', '{}', ';'))

То, что у вас есть, это в основном способ сделать это. У вас есть три разные вещи, которые вы координируете: 1) ходить по дереву, 2) работать только с файлами.rpmsave и 3) удалять эти файлы. Где бы вы нашли что-то, что изначально делает все это, не объясняя это? Команда Bash и код Python имеют примерно одинаковую сложность, что неудивительно.

Но вы должны исправить свой код, например так:

for root,files,subdirs in os.walk('/tmp/mount'):
    for file in files:
        if file.endswith('.rpmsave'):
            os.remove(os.path.join(root, file))

Если вы обнаружите, что делаете это много. Это может быть полезной оболочкой для os.walk:

def files(dir):
   # note you have subdirs and files flipped in your code
   for root,subdirs,files in os.walk(dir):
      for file in files:
         yield os.path.join(root,file)

Чтобы удалить группу файлов с определенным расширением внутри каталога:

[os.remove(file) for file in files(directory) if file.endswith('.extension')]
Другие вопросы по тегам