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

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

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

pythonpy - хороший конкурент awk и sed, использующий синтаксис python: github.com/Russell91/pythonpy

RussellStewart 13.09.2014 09:57

вы можете использовать shellpy, который был разработан с целью заменить bash / sh на python github.com/lamerman/shellpy

Alexander Ponomarev 14.02.2016 18:29

Это мой вопрос, я не понимаю, почему он основан на мнении. В верхнем ответе перечислены все основные функции оболочки и рассказывается, как это делать в Python. Это, на мой взгляд, ответ на вопрос, не связанный с мнением.

Chris Jefferson 09.04.2018 13:03

Этот вопрос и его закрытие обсуждаются на мета здесь

Erik A 18.04.2018 13:40
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
242
4
114 215
17
Перейти к ответу Данный вопрос помечен как решенный

Ответы 17

Предлагаю классную онлайн-книгу Погрузитесь в Python. Так я изначально выучил язык.

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

... основная проблема ответов только по ссылкам.

Jean-François Fabre 26.03.2018 22:58
Ответ принят как подходящий

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

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

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

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

  • Возможности программирования оболочки. Это вся проверка кода состояния процесса, различные логические команды (if, while, for и т. д.), Тестовая команда и все ее родственники. Материал определения функции. В Python все это намного проще. Это одна из огромных побед в избавлении от bash и использовании его на Python.

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

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

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

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

  1. Замените AWK и PERL на Python. Оставьте все остальное в покое.
  2. Посмотрите, как заменить GREP на Python. Это может быть немного сложнее, но ваша версия GREP может быть адаптирована к вашим потребностям в обработке.
  3. Посмотрите, как заменить FIND циклами Python, использующими os.walk. Это большая победа, потому что вы не создаете столько процессов.
  4. Посмотрите, как заменить обычную логику оболочки (циклы, решения и т. д.) Скриптами Python.

Также (из stackoverflow.com/questions/3479728/…) для расширения шаблонов пути / имени файла есть модуль "glob": docs.python.org/library/glob.html

Nickolay 03.10.2010 23:51

Запуск сценария bash из python: stackoverflow.com/questions/2651874/embed-bash-in-python/…

Nickolay 04.10.2010 00:00

написал: «Возможности взаимодействия. Это включает в себя историю команд и тому подобное. Вам это не нужно». Боюсь, что никто не может сказать, что человеку на самом деле нужно, а что нет. Возможно, он знает. Кроме того, эти возможности имеют большой смысл в интерактивной оболочке, на примере разницы между Idle и IPython.

heltonbiker 21.03.2011 19:44

Я искренне желаю, чтобы люди вообще отказались от сценариев оболочки. Я понимаю, что хакерство - это практически религия в мире * nix, но я действительно устал пытаться интерпретировать все хакерские обходные пути, внедренные в ОС. Новизна микроинструментов (awk, sed, top, base и т. д.) Прошла с того дня, как каждый решил выпустить свою версию. Я вздрагиваю, когда представляю, сколько человеко-часов потрачено на дрянные маленькие инструменты, которые можно легко заменить парой хорошо спроектированных модулей Python. ::вздох::

Evan Plaice 21.02.2012 14:07

Я не согласен с @EvanPlaice, потому что версия Python нескольких скриптов find, которые у меня есть, уродлива, длинна и неудобна в сравнении. Многое из сценариев оболочки должно быть, многое другое не следует. Не все должно быть только одним из Python или BASH (или чего-то еще).

mikebabcock 02.10.2012 08:04

@mikebabcock В идеале должна быть полная библиотека, реализующая все микроинструменты, доступные в базовом стеке * nix. Были бы включены такие функции, как find () и last (), и вместо каналов комбинация каррирования и ленивой загрузки справилась бы со склейкой всего этого. Разве не было бы неплохо иметь среду сценариев POSIX, которая стандартным образом работает во всех дистрибутивах? Ничего подобного пока нет ...

Evan Plaice 03.10.2012 20:59

Пункт о конвейерах оболочки (таких как (a | b; c ) | something >result) несколько смягчается тем, что тривиально легко передать конвейеры оболочки в методы subprocess с использованием shell=True.

iruvar 24.05.2013 05:17

@mikebabcock Многие вещи должны быть сценариями оболочки, многие - нет. Не все должно быть только одним из Python или BASH (или чего-то еще). Таким образом, сценарии оболочки не обязательно должны быть написаны на Bash.

Gill Bates 23.08.2014 11:51

Если ваши манипуляции с текстовым файлом обычно разовые, возможно, выполняются в приглашении оболочки, вы не получите ничего лучшего от 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, они в первую очередь вам понадобятся.

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

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

  • Если вы хотите использовать Python в качестве оболочки, почему бы не взглянуть на IPython? Также хорошо изучать язык в интерактивном режиме.
  • Если вы много работаете с текстом и используете Vim в качестве текстового редактора, вы также можете напрямую писать плагины для Vim на python. просто введите ": help python" в Vim и следуйте инструкциям или посмотрите этот презентация. Так легко и эффективно писать функции, которые вы будете использовать прямо в своем редакторе!

есть профиль ipython под названием 'sh', который делает интерпретатор очень очень похожим на оболочку.

Autoplectic 24.02.2009 23:22

Профиль ipython 'sh' уже давно удален.

gdw2 20.05.2013 23:40

>>> результат =! dmesg | grep -i 'usb' #the! оператор делает все

Permafacture 09.11.2013 21:14

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

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

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

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

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

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

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

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

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

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

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

"The Pyed Piper", or pyp, is a linux command line text manipulation tool similar to awk or sed, but which uses standard python string and list methods as well as custom functions evolved to generate fast results in an intense production environment.

Также посмотрите Envoy, который является альтернативой sh github.com/kennethreitz/envoy

AllanLRH 10.06.2015 16:37

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

#!/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 на команды системной оболочки и его использование как системная оболочка.

Проголосовали за, потому что по какой-то странной причине никто другой не упомянул! -Команды в IPython, которые являются абсолютно ключевыми; тем более, что вы также можете назначить их вывод переменной (список строк), как в filelines = ! cat myfile

kampu 24.05.2013 05:04

И вы можете использовать переменные Python как $var в команде оболочки? Вау. Это должен быть принятый ответ.

Chiel ten Brinke 17.03.2016 15:08

И вы также можете использовать его из записных книжек jupyter

Yuval Atzmon 09.03.2017 13:01

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

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

«программа, написанная на стандартном Python, будет работать даже в Windows»: без шуток?

Jean-François Fabre 26.03.2018 23:07

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

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

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

Для питона:

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

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

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

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

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

Он содержит общие команды в оболочке, и моя библиотека использует в основном тот же синтаксис, что и оболочка. например, cp (источник, назначение) может обрабатывать как файл, так и папку! (обертка shutil.copy shutil.copytree, и она решает, когда использовать какой). Более того, он может поддерживать векторизацию, как R!

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

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

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

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

Greg Dubicki 13.10.2016 20:40

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

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

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

env | uniq | sort -r | grep PATH

или же

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

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

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

  • Компилирует, оценивает и выполняет!
  • История команд и завершение вкладки
  • Помощь и суперпомощь с ? и ??
  • Псевдонимы и индивидуальные подсказки
  • Выполняет команды и / или сценарии *.xsh, которые также можно импортировать
  • Переменные среды, включая поиск с помощью ${}
  • Перенаправление ввода / вывода и объединение
  • Фоновые задания и контроль заданий
  • Вложенные подпроцессы, трубы и сопроцессы
  • Режим подпроцесса, если команда существует, в противном случае - режим Python
  • Захваченный подпроцесс с $(), незахваченный подпроцесс с $[], оценка Python с @()
  • Подстановка имен файлов с помощью * или подстановка имен файлов регулярных выражений с помощью обратных кавычек

Но почему кажется, что все эти ответы просто изобретают колесо для людей, которые не знают баш? Я в меру освоился с bash, и каждый из этих ответов выглядит так, как будто в конечном итоге он принесет больше работы с небольшой пользой. Все эти ответы нацелены на людей-питонов, которые боятся (или не хотят тратить время на изучение) bash, я прав?

Buttle Butkus 13.07.2017 10:34

Похоже, у него есть некоторые недостатки, такие как требование использовать расширение .xsh для файлов с кодом xonsh: github.com/xonsh/xonsh/issues/2478. В противном случае вам придется использовать evalx, чтобы вызывать его непосредственно из файлов .py.

Andry 14.08.2017 14:52

Вы можете использовать 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' в оболочке, а затем присвоит результат переменной журнала. Результат имеет следующие свойства:

стандартный вывод весь текст из стандартного вывода выполняемого процесса

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

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

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

Другие вопросы по теме