Як реалізувати загальні ідіоми bash в Python? [зачинено]


242

Наразі я маніпулюю текстовим файлом через купу погано запам’ятовуваних AWK, sed, Bash та крихітного шматочка Perl.

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


3
pythonpy є хорошим конкурентом для awk і sed, використовуючи синтаксис python: github.com/Russell91/pythonpy
RussellStewart

4
ви можете використовувати shellpy, розроблений з ідеєю, щоб замінити bash / sh python github.com/lamerman/shellpy
Олександр Пономарьов

Це моє запитання, я не розумію, чому це базується на думці. У верхній відповіді перераховано кожне з головних речей, які робить оболонка, і розповідається, як їх робити в python. Це, на мій погляд, відповідає на це питання не думкою.
Кріс Джефферсон

Це питання, і це питання закрито, обговорюється на мета тут
Ерік А

Відповіді:


144

Будь-яка оболонка має кілька наборів функцій.

  • Основні команди Linux / Unix. Все це доступно через бібліотеку підпроцесів . Це не завжди найкращий перший вибір для виконання всіх зовнішніх команд. Подивіться також на shutil на деякі команди, які є окремими командами Linux, але ви, ймовірно, могли реалізовуватися безпосередньо у ваших скриптах Python. Ще одна величезна партія команд Linux знаходиться в бібліотеці ОС ; ви можете зробити це простіше просто в Python.

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

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

  • Особливості програмування оболонки. Це вся перевірка коду статусу процесу, різні логічні команди (якщо, поки, для тощо) тестова команда та всі її родичі. Функція визначення функції. Це все набагато, набагато простіше в Python. Це одна з величезних перемог у тому, щоб позбутися баш та зробити це на Python.

  • Особливості взаємодії. Сюди входить історія команд і що ні. Це вам не потрібно для написання скриптів оболонок. Це стосується лише взаємодії людини, а не для написання сценарію.

  • Особливості управління файлами оболонки. Сюди входить перенаправлення та трубопроводи. Це хитріше. Багато з цього можна зробити за допомогою підпроцесу. Але деякі речі, легкі в оболонці, неприємні для Python. Зокрема, такі речі (a | b; c ) | something >result. Це виконує два процеси паралельно (з виведенням aяк вхід до b), після чого йде третій процес. Вихід з цієї послідовності виконується паралельно, somethingа вихід збирається у файл з назвою result. Це просто складно виразити будь-якою іншою мовою.

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

Найкраще, що ви можете це робити поетапно.

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

6
писав: "Особливості взаємодії. Це включає в себе історію команд і що ні. Це вам не потрібно." Боюся, ніхто не міг сказати, що людині справді потрібно чи ні. Можливо, він і робить. Крім того, ці засоби мають багато сенсу в інтерактивній оболонці, беручи за приклад різницю між Idle та IPython.
heltonbiker

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

40
Я не погоджуюся з @EvanPlaice, оскільки версія python кількох findскриптів у мене є некрасивою і довгою та нездійсненною у порівнянні. Багато речей повинні бути сценаріями оболонок, багато інших не повинні . Не все повинно бути лише одним з Python або BASH (або будь-що інше).
mikebabcock

8
@mikebabcock В ідеалі була б повна бібліотека, яка реалізує всі мікроінструменти, доступні базовим стеком * nix. Були б включені такі функції, як find () та last (), а замість труб комбінація currying та lezy-load оброблятиме їх склеюванням. Не було б непогано мати сценарій сценарію POSIX, який працює стандартним чином у всіх дистрибутивах? Нічого подібного не існує, але ...
Еван Плейс

2
Суть про оболонки трубопроводів (таких як (a | b; c ) | something >result) дещо пом'якшується тим, що тривіально легко передати subprocessshell=True
оболонні

103

Так, звісно :)

Погляньте на ці бібліотеки, які допоможуть вам ніколи більше не писати сценарії оболонки (девіз Plumbum).

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

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


Також подивіться на Послання
AllanLRH

57

Я щойно з’ясував, як поєднувати найкращі частини баш та іпітон. На сьогоднішній день це мені здається зручнішим, ніж використання підпроцесу тощо. Ви можете легко скопіювати великі частини існуючих скриптів 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
kampu

І ви можете використовувати змінні python, як $varу команді shell? Ого. Це має бути прийнятою відповіддю.
Chiel ten Brinke

І ви також можете використовувати його з зошитів з юпітера
Юваль Атцмон

44

Починаючи з 2015 року та випуску Python 3.4, тепер достатньо повноцінна інтерактивна оболонка, доступна на веб- сайті: http://xon.sh/ або https://github.com/scopatz/xonsh

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

Xonsh ('раковина') дуже намагається наслідувати баш, тому речі, для яких ви вже здобули м'язову пам'ять, наприклад

env | uniq | sort -r | grep PATH

або

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

все одно буде добре працювати.

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

  • Компілює, оцінює та виконує!
  • Історія команд та завершення вкладки
  • Довідка та супердопомога з ?&??
  • Псевдоніми та індивідуальні підказки
  • Виконує команди та / або *.xshскрипти, які також можна імпортувати
  • Змінні середовища, включаючи пошук за допомогою ${}
  • Перенаправлення та комбінування вводу / виводу
  • Основні завдання та контроль роботи
  • Вкладені підпроцеси, труби та копроцеси
  • Підпроцесовий режим, коли існує команда, режим Python в іншому випадку
  • Захоплений підпроцес з $(), незахоплений підпроцес з $[], оцінка Python з@()
  • Ім'я файлу Globbing з *або Регулярне вираження Ім'я файлу Globbing за допомогою зворотних посилань

Але чому здається, що всі ці відповіді просто винаходять колесо для людей, які не знають башти ? Мені досить зручно баш, і кожен з цих відповідей виглядає так, що це в кінцевому підсумку буде більше роботи за невелику користь. Ці відповіді спрямовані на людей-пітонів, які бояться (або не хочуть витрачати час на навчання) баш, я прав?
Buttle Butkus

Здається, у нього є деякі недоліки, як вимога використовувати .xshрозширення для файлів з кодом xonsh : github.com/xonsh/xonsh/isissue/2478 . Інакше вам доведеться використовувати його evalxдля виклику безпосередньо з .pyфайлів.
Андрій

31
  • Якщо ви хочете використовувати Python як оболонку, чому б не подивитися на IPython ? Добре також інтерактивно вивчати мову.
  • Якщо ви багато працюєте з текстом, і якщо ви використовуєте Vim як текстовий редактор, ви також можете безпосередньо писати плагіни для Vim в python. просто введіть ": help python" у Vim та дотримуйтесь інструкцій чи ознайомтесь із цією презентацією . Написати функції так просто і потужно, що ви будете використовувати безпосередньо у своєму редакторі!

8
є профіль ipython під назвою "sh", що робить перекладача дуже схожим на оболонку.
Autoplectic

3
Профіль ipython 'sh' видалено вже деякий час.
gdw2

>>> результат =! dmesg | grep -i 'usb' #те! оператор робить це все
Permafacture

16

На початку було sh, sed, and awk (і знахідка, і греп, і ...). Це було добре. Але awk може бути дивним маленьким звіром і важко запам'ятати, якщо ви не використовуєте його часто. Тоді великий верблюд створив Перл. Перл був мрією системного адміністратора. Це було як сценарій оболонки на стероїди. Обробка тексту, включаючи регулярні вирази, була лише частиною мови. Потім стало потворно ... Люди намагалися робити великі програми з Perl. Тепер, не зрозумійте мене неправильно, Perl може бути додатком, але він може (може!) Виглядати безладно, якщо ви не дуже обережні. Тоді є весь цей бізнес з плоскими даними. Досить загнати гайки програміста.

Введіть Python, Ruby та ін. Це дійсно дуже хороші мови загального призначення. Вони підтримують обробку тексту і роблять це добре (хоча, можливо, не так щільно вплетені в основний ядро ​​мови). Але вони також дуже масштабуються, і в кінці робочого дня все ще мають гарний вигляд. Вони також розробили досить здоровенні громади з великою кількістю бібліотек для майже нічого.

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

У будь-якому випадку, удачі!


9

Я пропоную дивовижну онлайн-книгу Dive Into Python . Так я спочатку вивчив мову.

Окрім того, що ви навчаєте основну структуру мови та цілу масу корисних структур даних, вона має добру главу про обробку файлів та наступні глави щодо регулярних виразів тощо.


1
... головне питання відповідей лише на посилання.
Жан-Франсуа Фабре


7

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

Ще краще, що програма, написана на стандартному Python, працюватиме навіть у Windows!


1
"програма, написана на стандартному Python, працюватиме навіть у Windows": не жартуєте?
Жан-Франсуа Фабре

6

Я дам тут свою думку на основі досвіду:

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

  • оболонка може дуже легко породжувати код лише для читання. Напишіть це, і коли ви повернетесь до нього, ви ніколи не зрозумієте, що ви зробили знову. Зробити це дуже просто.
  • оболонка може робити ВЕЛИКОГО обробку тексту, розбивання тощо в одному рядку з трубами.
  • це найкраща мова клею, коли йдеться про інтеграцію виклику програм у різні мови програмування.

Для пітона:

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

Зазвичай я вибираю bash для більшості речей, але коли у мене є щось, що повинно перетинати межі windows, я просто використовую python.


4

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

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

3

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


3

Досліджуючи цю тему, я знайшов цей код підтвердження концепції (через коментар на веб-сайті 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)

2

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

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


2

Ви можете використовувати 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 виконаного процесу

return code return code виконання

Це загальний огляд бібліотеки, більш детальний опис із прикладами можна знайти тут .


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, вони - перше, що вам знадобиться.


1

Я опублікував пакет на PyPI: ez .
Використовуйте pip install ezдля його встановлення.

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

Інший приклад: немає os.walk, використовуйте fls (path, regex) для рекурсивного пошуку файлів і фільтру з регулярним виразом, і він повертає список файлів з повним шляхом або без нього

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

Однозначно перевірити це! Написати / покращити це мені коштувало сотні годин!


1
Виглядає цікаво, але я не можу пробити неформатовані документи на pypi.python.org/pypi/ez , вибачте ...
Грег Дубіцький
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.