Как реализовать общие идиомы Bash в Python?

247

В настоящее время я выполняю манипуляции с текстовыми файлами через кучу плохо запоминаемых AWK, sed, Bash и крошечный бит Perl.

Я видел несколько мест, которые питон хорош для такого рода вещей, я знаю немного, и я хотел бы узнать больше. Является ли Python хорошим выбором для этого, и есть ли хорошая книга или руководство по обучению использованию Python для замены сценариев оболочки, AWK, sed и друзей?

  • 3
    pythonpy - хороший конкурент для awk и sed, использующих синтаксис python: github.com/Russell91/pythonpy
  • 4
    Вы можете использовать shellpy, который был разработан с идеей, чтобы заменить bash / sh на python github.com/lamerman/shellpy
Показать ещё 2 комментария
Теги:

19 ответов

133
Лучший ответ

Любая оболочка имеет несколько наборов функций.

  • Основные команды Linux/Unix. Все они доступны через библиотеку subprocess. Это не всегда лучший выбор для всех внешних команд. Посмотрите также на shutil для некоторых команд, которые являются отдельными командами Linux, но вы, вероятно, могли бы реализовать прямо в своих сценариях Python. Еще одна огромная партия команд Linux находится в библиотеке os; вы можете сделать это проще всего на Python.

    И - бонус! -- быстрее. Каждая отдельная команда Linux в оболочке (за некоторыми исключениями) разворачивает подпроцесс. Используя модули Python shutil и os, вы не форкируете подпроцесс.

  • Особенности среды оболочки. Сюда входит материал, который устанавливает командную среду (текущий каталог и переменные среды, а что нет). Вы можете легко управлять этим с Python напрямую.

  • Функции программирования оболочки. Это все проверки кода состояния процесса, различные логические команды (если, в то время, для и т.д.) Команда тестирования и все ее родственники. Свойство определения функции. В Python это намного проще, намного проще. Это одна из огромных побед в избавлении от bash и выполнение этого в Python.

  • Функции взаимодействия. Это включает в себя историю команд, а что - нет. Это не нужно для написания сценариев оболочки. Это только для взаимодействия человека, а не для script -writing.

  • Функции управления файлами оболочки. Это включает перенаправление и трубопроводы. Это сложнее. Большая часть этого может быть выполнена с помощью подпроцесса. Но некоторые вещи, которые легко в оболочке, неприятны в Python. В частности, такие вещи, как (a | b; c ) | something >result. Он выполняет два процесса параллельно (с выходом a в качестве входных данных для b), а затем третий процесс. Выход из этой последовательности запускается параллельно с something, и вывод собран в файл с именем result. Это просто сложно выразить на любом другом языке.

Конкретные программы (awk, sed, grep и т.д.) часто могут быть переписаны как модули Python. Не заходите за борт. Замените то, что вам нужно, и разработайте модуль "grep". Не начинайте писать модуль Python, который заменяет "grep".

Самое лучшее, что вы можете сделать это пошагово.

  • Замените AWK и PERL на Python. Оставьте все остальное в одиночестве.
  • Посмотрите на замену GREP на Python. Это может быть немного сложнее, но ваша версия GREP может быть адаптирована к вашим потребностям в обработке.
  • Посмотрите на замену FIND на петли Python, которые используют os.walk. Это большая победа, потому что вы не создаете столько процессов.
  • Посмотрите на замену общей оболочки (петли, решения и т.д.) с помощью скриптов Python.
  • 1
    Также (из stackoverflow.com/questions/3479728/… ) для расширения шаблонов пути / имени файла есть модуль «glob»: docs.python.org/library/glob.html
  • 0
    Запуск скрипта bash из python: stackoverflow.com/questions/2651874/embed-bash-in-python/…
Показать ещё 6 комментариев
106

Да, конечно:)

Посмотрите на эти библиотеки, которые помогут вам Никогда не писать сценарии оболочки снова (девиз Plumbum).

Кроме того, если вы хотите заменить awk, sed и grep на что-то основанное на Python, я рекомендую pyp -

"The Pyed Piper", или pyp, представляет собой текстовую манипуляцию в командной строке linux инструмент, подобный awk или sed, но который использует стандартную строку python и список, а также настраиваемые функции, разработанные для быстрого создания приводит к интенсивной производственной среде.

  • 0
    Также взгляните на Envoy, который является альтернативой sh github.com/kennethreitz/envoy
54

Я только что узнал, как объединить лучшие части bash и ipython. До сих пор это кажется мне более удобным, чем использование подпроцесса и так далее. Вы можете легко скопировать большие части существующих скриптов bash и, например, добавить обработку ошибок в пути python:) И вот мой результат:

#!/usr/bin/env ipython3

# *** How to have the most comfort scripting experience of your life ***
# ######################################################################
#
# … by using ipython for scripting combined with subcommands from bash!
#
# 1. echo "#!/usr/bin/env ipython3" > scriptname.ipy    # creates new ipy-file
#
# 2. chmod +x scriptname.ipy                            # make in executable
#
# 3. starting with line 2, write normal python or do some of
#    the ! magic of ipython, so that you can use unix commands
#    within python and even assign their output to a variable via
#    var = !cmd1 | cmd2 | cmd3                          # enjoy ;)
#
# 4. run via ./scriptname.ipy - if it fails with recognizing % and !
#    but parses raw python fine, please check again for the .ipy suffix

# ugly example, please go and find more in the wild
files = !ls *.* | grep "y"
for file in files:
  !echo $file | grep "p"
# sorry for this nonsense example ;)

См. документы IPython в командах командной оболочки и используя как систему оболочки.

  • 11
    Проголосовал, потому что по какой-то странной причине никто больше не упомянул! -Команды в IPython, которые являются абсолютно ключевыми; тем более, что вы также можете назначить их вывод переменной (список строк), как в filelines = ! cat myfile
  • 0
    И вы можете использовать переменные python как $var в команде оболочки? Вот это да. Это должен быть принятый ответ.
Показать ещё 1 комментарий
42

Начиная с версии 2015 года и версии Python 3.4, теперь доступна достаточно полная интерактивная интерактивная оболочка: http://xon.sh/ или https://github.com/scopatz/xonsh

В демонстрационном видео не отображаются используемые каналы, но они поддерживаются в режиме оболочки по умолчанию.

Xonsh ('conch') очень сильно пытается эмулировать bash, поэтому вещи, которые вы уже накопили для мышечной памяти, например

env | uniq | sort -r | grep PATH

или

my-web-server 2>&1 | my-log-sorter

все равно будет работать нормально.

Учебник достаточно длинный и, по-видимому, охватывает значительную часть функциональности, которую обычно ожидали бы от пепла или приглашения bash:

  • Скомпилирует, оценивает и выполняет!
  • История команд и вкладка
  • Помощь и суперпомех? и
  • Псевдонимы и настраиваемые приглашения
  • Выполняет команды и/или *.xsh скрипты, которые также можно импортировать
  • Переменные среды, включая поиск с помощью ${}
  • Перенаправление и объединение ввода/вывода
  • Фоновые задания и управление заданиями
  • Вложенные подпроцессы, трубы и сопроцессоры
  • Режим подпроцесса, когда существует команда, Python-mode иначе
  • Захваченный подпроцесс с $(), Uncaptured Subprocess с $[], оценка Python с помощью @()
  • Имя файла Globbing с * или регулярным выражением Имя файла Globbing with Backticks
  • 0
    Но почему кажется, что все эти ответы просто заново изобретают колесо для людей, которые не знают bash ? Мне стало довольно комфортно с bash, и каждый из этих ответов выглядит так, что в конечном итоге это будет больше работы с небольшой пользой. Все эти ответы нацелены на людей, питонов, которые боятся (или не хотят тратить время на изучение) Баш, я прав?
  • 0
    Кажется, у него есть некоторые недостатки, такие как требование использовать расширение .xsh для файлов с кодом xonsh: github.com/xonsh/xonsh/issues/2478 . В противном случае вы должны использовать evalx чтобы вызывать его непосредственно из файлов .py .
31
  • Если вы хотите использовать Python в качестве оболочки, почему бы не взглянуть на IPython? Также полезно интерактивно изучать язык.
  • Если вы много манипулируете текстами, и если вы используете Vim в качестве текстового редактора, вы также можете напрямую писать плагины для Vim в python. просто введите ": help python" в Vim и следуйте инструкциям или посмотрите на presentation. Это так просто и мощно, чтобы писать функции, которые вы будете использовать непосредственно в своем редакторе!
  • 8
    есть профиль ipython под названием 'sh', который делает интерпретатор очень похожим на оболочку.
  • 3
    Профиль ipython 'sh' уже давно удален.
Показать ещё 1 комментарий
18

В начале были sh, sed и awk (и find, и grep, и...). Это было хорошо. Но awk может быть странным маленьким зверем и трудно запоминать, если вы его не используете часто. Тогда великий верблюд создал Перла. Perl был мечтой системного администратора. Это было похоже на сценарий оболочки на стероидах. Обработка текста, включая регулярные выражения, была лишь частью языка. Тогда это стало уродливо... Люди пытались сделать большие приложения с Perl. Теперь, не поймите меня неправильно, Perl может быть приложением, но он может (может!) Выглядеть как беспорядок, если вы не очень осторожны. Тогда есть весь этот бизнес с плоскими данными. Этого достаточно, чтобы управлять гайками программистов.

Введите Python, Ruby и др. Это действительно очень хорошие языки общего назначения. Они поддерживают обработку текста и делают это хорошо (хотя, возможно, не так тесно связаны в основном ядре языка). Но они также расширяются очень хорошо, и в конце дня все еще есть красивый код. Они также разработали довольно здоровенные сообщества с большим количеством библиотек для большинства вещей.

Теперь большая часть негативности для Perl - это вопрос мнения, и, конечно же, некоторые люди могут писать очень чистый Perl, но с этим множеством людей, жалующихся на то, что слишком легко создать запутанный код, вы знаете, что некоторые части истины там. На самом деле возникает вопрос: собираетесь ли вы использовать этот язык для более простых замен bash script. Если нет, узнайте еще несколько Perl.. это абсолютно фантастично для этого. Если, с другой стороны, вам нужен язык, который будет расти вместе с вами, как вы хотите сделать больше, могу ли я предложить Python или Ruby.

В любом случае, удачи!

11

Я предлагаю потрясающую онлайн-книгу Dive Into Python. Это как я изучил язык изначально.

Beyone, преподающий вам базовую структуру языка и множество полезных структур данных, имеет хорошую главу в обработке файлов и последующие главы в регулярные выражения и т.д.

  • 1
    ... основной вопрос ответов только для ссылок.
9

Одна из причин, по которой я люблю Python, состоит в том, что он намного лучше стандартизирован, чем инструменты POSIX. Я должен удвоить и утроить проверку того, что каждый бит совместим с другими операционными системами. Программа, написанная в системе Linux, может работать не так же в BSD-системе OSX. С Python мне просто нужно проверить, что целевая система имеет достаточно современную версию Python.

Даже лучше, программа, написанная на стандартном Python, будет работать даже в Windows!

  • 1
    «Программа, написанная на стандартном Python, будет работать даже на Windows»: не шучу?
7

Добавление к предыдущим ответам: проверьте модуль pexpect для работы с интерактивными командами (adduser, passwd и т.д.)

6

Я приведу здесь свое мнение, основанное на опыте:

Для оболочки:

  • оболочка может очень легко порождать код только для чтения. Напишите его, и когда вы вернетесь к нему, вы никогда не узнаете, что вы сделали снова. Это очень легко сделать.
  • оболочка может выполнять много обработки текста, разбиения и т.д. в одной строке с помощью труб.
  • Это лучший язык для клея, когда речь идет о включении вызова программ на разных языках программирования.

Для python:

  • Если вы хотите переносимость к включенным окнам, используйте python.
  • python может быть лучше, если вы должны манипулировать только текстом, например, коллекциями чисел. Для этого я рекомендую python.

Я обычно выбираю bash для большинства вещей, но когда у меня есть что-то, что должно пересекать границы окон, я просто использую python.

5

У меня построены полудлинные сценарии оболочки (300-500 строк) и код Python, который выполняет аналогичную функциональность. Когда выполняется множество внешних команд, я считаю, что оболочка проще в использовании. Perl также является хорошим вариантом, когда есть много текстовых манипуляций.

3

pythonpy - это инструмент, который обеспечивает легкий доступ ко многим функциям от awk и sed, но с использованием синтаксиса python:

$ echo me2 | py -x 're.sub("me", "you", x)'
you2
3

Во время исследования этой темы я нашел этот код доказательной концепции (через комментарий http://jlebar.com/2010/2/1/Replacing_Bash.html), который позволяет вам писать shell-подобные конвейеры в Python, используя краткий синтаксис, и использовать существующие системные инструменты там, где они имеют смысл ":

for line in sh("cat /tmp/junk2") | cut(d=',',f=1) | 'sort' | uniq:
    sys.stdout.write(line)
3

Ваш лучший выбор - это инструмент, специально предназначенный для вашей проблемы. Если он обрабатывает текстовые файлы, то Sed, Awk и Perl являются главными соперниками. Python - динамический язык общего назначения. Как и в случае с любым языком общего назначения, существует поддержка манипуляции с файлами, но это не то, что является основной целью. Я бы рассмотрел Python или Ruby, если бы у меня было требование для динамического языка в частности.

Короче говоря, изучите Sed и Awk очень хорошо, плюс все другие плюсы, которые приходят с вашим вкусом * nix (все Bash встроенные, grep, tr и т.д.). Если вам нужна текстовая обработка файлов, вы уже используете нужный материал.

1

Я хочу, чтобы было что-то достойное, чтобы заменить скрипты bash, но на самом деле нет.

Python будет казаться отличным кандидатом, пока вы не столкнетесь с неудобными стандартными библиотечными функциями для обработки файлов и процессов нереста (os.popen3) и общаетесь с ними.

1

Вы можете использовать python вместо bash с помощью библиотеки ShellPy.

Вот пример, который загружает аватара пользователя Python из Github:

import json
import os
import tempfile

# get the api answer with curl
answer = `curl https://api.github.com/users/python
# syntactic sugar for checking returncode of executed process for zero
if answer:
    answer_json = json.loads(answer.stdout)
    avatar_url = answer_json['avatar_url']

    destination = os.path.join(tempfile.gettempdir(), 'python.png')

    # execute curl once again, this time to get the image
    result = `curl {avatar_url} > {destination}
    if result:
        # if there were no problems show the file
        p`ls -l {destination}
    else:
        print('Failed to download avatar')

    print('Avatar downloaded')
else:
    print('Failed to access github api')

Как вы можете видеть, все выражения внутри символа серьезного акцента (`) выполняются в оболочке. А в коде Python вы можете записывать результаты этого выполнения и выполнять на нем действия. Например:

log = `git log --pretty=oneline --grep='Create'

Эта строка сначала выполнит git log --pretty=oneline --grep='Create' в оболочке, а затем назначит результат переменной журнала. Результат имеет следующие свойства:

stdout весь текст из stdout выполненного процесса

stderr весь текст из stderr выполненного процесса

returncode код возврата выполнения

Это общий обзор библиотеки, более подробное описание с примерами можно найти здесь.

1

Я опубликовал пакет на PyPI: ez.
Используйте pip install ez, чтобы установить его.

У него есть упакованные общие команды в оболочке, и моя библиотека использует в основном тот же синтаксис, что и shell. например, cp (source, destination) может обрабатывать как файл, так и папку! (wrapper of shutil.copy shutil.copytree, и он решает, когда использовать какой). Еще лучше, он может поддерживать векторизацию, такую ​​как R!

Другой пример: no os.walk, использовать fls (путь, регулярное выражение), чтобы рекурсивно находить файлы и фильтровать с регулярным выражением, и возвращает список файлов с или без полного пути

Окончательный пример: вы можете комбинировать их для написания очень простых скриптов:
files = fls('.','py$'); cp(files, myDir)

Определенно проверьте это! Мне стоило сотни часов, чтобы написать/улучшить его!

  • 1
    Выглядит интересно, но я не могу пробиться через неформатированные документы на pypi.python.org/pypi/ez , извините ...
1

Если ваши манипуляции с текстовым файлом обычно одноразовые, возможно, сделанные в командной строке, вы не получите ничего лучшего от python.

С другой стороны, если вам обычно приходится повторять одну и ту же (или подобную) задачу снова и снова, и вы должны писать свои скрипты для этого, то python отлично работает, и вы можете легко создавать свои собственные библиотеки ( вы можете сделать это с помощью сценариев оболочки, но это более громоздко).

Очень простой пример, чтобы почувствовать себя.

import popen2
stdout_text, stdin_text=popen2.popen2("your-shell-command-here")
for line in stdout_text:
  if line.startswith("#"):
    pass
  else
    jobID=int(line.split(",")[0].split()[1].lstrip("<").rstrip(">"))
    # do something with jobID

Проверьте также модуль sys и getopt, они будут первыми, которые вам понадобятся.

0

Python отлично справится с текстовыми файлами. Для изучения проверьте здесь.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню