webentwicklung-frage-antwort-db.com.de

Wie implementiere ich gemeinsame Bash-Redewendungen in Python?

Momentan bearbeite ich meine Textdateien mit ein paar schlecht gemerkten AWK, sed, Bash und ein bisschen Perl.

Ich habe ein paar Stellen erwähnt, an denen python gut für diese Art von Dingen geeignet ist. Wie kann ich Python anstelle von Shell Scripting, AWK, sed und Freunde?

242
Chris Jefferson

Jede Shell verfügt über mehrere Funktionen.

  • Die Essential Linux/Unix-Befehle. Alle diese sind über die nterprozess Bibliothek verfügbar. Dies ist nicht immer die beste erste Wahl, um all externe Befehle auszuführen. Schauen Sie sich auch shutil für einige Befehle an, die separate Linux-Befehle sind, aber Sie könnten sie wahrscheinlich direkt in Ihren Python Skripten implementieren. Ein weiterer großer Stapel von Linux-Befehlen befindet sich in - os library, das geht in Python einfacher.

    Und - Bonus! -- schneller. Jeder einzelne Linux-Befehl in der Shell (mit wenigen Ausnahmen) gibt einen Unterprozess aus. Mit den Modulen Python shutil und os wird kein Unterprozess gegabelt.

  • Die Shell-Umgebung verfügt über. Dies beinhaltet Dinge, die die Umgebung eines Befehls festlegen (aktuelle Verzeichnis- und Umgebungsvariablen und was nicht). Sie können dies einfach über Python direkt verwalten.

  • Die Shell-Programmierfunktionen. Dies ist die Überprüfung des gesamten Prozessstatuscodes, der verschiedenen Logikbefehle (wenn, während, für usw.) des Testbefehls und aller seiner Verwandten. Das Funktionsdefinitionsmaterial. In Python ist das alles viel einfacher. Dies ist einer der großen Siege, wenn es darum geht, Bash loszuwerden und es in Python zu tun.

  • Interaktionsfunktionen. Dies beinhaltet den Befehlsverlauf und was nicht. Sie benötigen dies nicht zum Schreiben von Shell-Skripten. Dies gilt nur für die menschliche Interaktion und nicht für das Schreiben von Skripten.

  • Die Shell-Dateiverwaltungsfunktionen. Dies schließt Umleitung und Pipelines ein. Das ist schwieriger. Vieles davon kann mit Unterprozessen erledigt werden. Aber einige Dinge, die in der Shell einfach sind, sind in Python unangenehm. Speziell Sachen wie (a | b; c ) | something >result. Dies führt zwei Prozesse parallel aus (mit der Ausgabe von a als Eingabe für b), gefolgt von einem dritten Prozess. Die Ausgabe dieser Sequenz wird parallel zu something ausgeführt und in einer Datei mit dem Namen result gesammelt. Es ist einfach kompliziert, das in einer anderen Sprache auszudrücken.

Bestimmte Programme (awk, sed, grep, etc.) können oft als Python Module. Gehen Sie nicht über Bord. Ersetzen Sie, was Sie brauchen und entwickeln Sie Ihr "grep" Modul. Tun Sie nicht Schreiben Sie zunächst ein Python - Modul, das "grep" ersetzt.

Das Beste ist, dass Sie dies in Schritten tun können.

  1. Ersetzen Sie AWK und Perl durch Python. Lass alles andere in ruhe.
  2. Sehen Sie sich an, wie Sie GREP durch Python ersetzen. Dies kann etwas komplexer sein, aber Ihre GREP-Version kann an Ihre Verarbeitungsanforderungen angepasst werden.
  3. Ersetzen Sie FIND durch Python Loops, die os.walk Verwenden. Dies ist ein großer Gewinn, da Sie nicht so viele Prozesse erzeugen.
  4. Sehen Sie sich an, wie Sie die allgemeine Shell-Logik (Schleifen, Entscheidungen usw.) durch Python Skripte) ersetzen.
144
S.Lott

Ja natürlich :)

Schauen Sie sich diese Bibliotheken an, die Ihnen helfen Schreiben Sie nie wieder Shell-Skripte (Plumbums Motto).

Wenn Sie awk, sed und grep durch etwas ersetzen möchten, das auf Python basiert, empfehle ich pyp -

"The Pyed Piper", oder pyp, ist ein Linux-Befehlszeilentext-Manipulationswerkzeug, das awk oder sed ähnelt, jedoch standardmäßige python string- und list-Methoden sowie benutzerdefinierte Funktionen verwendet, die entwickelt wurden, um schnell zu generieren führt zu einer intensiven Produktionsumgebung.

103
Piotr Dobrogost

Ich habe gerade herausgefunden, wie man die besten Teile von Bash und Ipython kombiniert. Bisher scheint mir das komfortabler zu sein als die Verwendung von Subprozessen und so weiter. Sie können problemlos große Teile bestehender Bash-Skripte kopieren und z. füge die Fehlerbehandlung auf die python Weise hinzu :) Und hier ist mein Ergebnis:

#!/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 ;)

Siehe IPython-Dokumente zu System-Shell-Befehle und deren Verwendung als System-Shell .

57
TheK

Ab 2015 und Python 3.4) ist jetzt eine einigermaßen vollständige benutzerinteraktive Shell unter folgender Adresse verfügbar: http://xon.sh/ oder https://github.com/scopatz/xonsh

Das Demonstrationsvideo zeigt keine verwendeten Pipes, sie werden jedoch im Standard-Shell-Modus unterstützt.

Xonsh ("Muschel") versucht sehr schwer, Bash zu emulieren, also Dinge, für die Sie bereits Muskelgedächtnis gewonnen haben, wie

env | uniq | sort -r | grep PATH

oder

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

wird immer noch gut funktionieren.

Das Tutorial ist recht langwierig und scheint einen erheblichen Teil der Funktionen abzudecken, die man normalerweise von einem Ash- oder Bash-Prompt erwartet:

  • Kompiliert, evaluiert und führt aus!
  • Befehlsverlauf und Tab-Vervollständigung
  • Hilfe & Superhilfe mit ? & ??
  • Aliase und benutzerdefinierte Eingabeaufforderungen
  • Führt Befehle und/oder *.xsh - Skripte aus, die auch importiert werden können
  • Umgebungsvariablen einschließlich Suche mit ${}
  • Eingabe/Ausgabe-Umleitung und Kombination
  • Hintergrundjobs & Job-Kontrolle
  • Verschachteln von Unterprozessen, Pipes und Coprozessen
  • Subprozess-Modus, wenn ein Befehl existiert, sonst Python-Modus
  • Erfasster Unterprozess mit $(), Nicht erfasster Unterprozess mit $[], Python Auswertung mit @()
  • Dateiname mit * Oder Dateiname mit regulären Ausdrücken mit Backticks
44
Kamilion
  • Wenn Sie Python als Shell verwenden möchten, werfen Sie einen Blick auf IPython ? Es ist auch gut, die Sprache interaktiv zu lernen.
  • Wenn Sie viel Text bearbeiten und Vim als Texteditor verwenden, können Sie Plugins für Vim auch direkt in Python schreiben. Geben Sie einfach ": help python" in Vim ein und folgen Sie den Anweisungen oder sehen Sie sich diese an Präsentation . Es ist so einfach und leistungsstark, Funktionen zu schreiben, die Sie direkt in Ihrem Editor verwenden werden!
31
Mapad

Am Anfang gab es sh, sed und awk (und find und grep und ...). Es war gut. Aber awk kann ein seltsames kleines Biest sein und schwer zu merken sein, wenn Sie es nicht oft benutzen. Dann schuf das große Kamel Perl. Perl war der Traum eines Systemadministrators. Es war wie ein Shell-Skript für Steroide. Textverarbeitung, einschließlich regulärer Ausdrücke, waren nur ein Teil der Sprache. Dann wurde es hässlich ... Die Leute versuchten, mit Perl große Anwendungen zu erstellen. Versteht mich nicht falsch, Perl kann eine Anwendung sein, aber es kann (kann!) Wie ein Chaos aussehen, wenn ihr nicht wirklich vorsichtig seid. Dann gibt es all diese Flat Data-Geschäfte. Es ist genug, um einen Programmierer verrückt zu machen.

Geben Sie Python, Ruby, et al. Das sind wirklich sehr gute Allzwecksprachen. Sie unterstützen die Textverarbeitung und tun dies gut (obwohl sie möglicherweise nicht so eng mit dem grundlegenden Kern der Sprache verwoben sind). Aber sie lassen sich auch sehr gut skalieren und haben am Ende des Tages immer noch gut aussehenden Code. Sie haben auch ziemlich starke Gemeinschaften mit vielen Bibliotheken für fast alles entwickelt.

Nun, ein Großteil der Negativität gegenüber Perl ist Ansichtssache, und sicherlich können einige Leute sehr sauberes Perl schreiben, aber da sich so viele Leute darüber beschweren, dass es zu einfach ist, verschleierten Code zu erstellen, wissen Sie, dass ein gewisses Maß an Wahrheit vorhanden ist. Dann stellt sich wirklich die Frage, ob Sie diese Sprache jemals für mehr als nur das Ersetzen von Bash-Skripten verwenden werden. Wenn nicht, lerne etwas mehr über Perl .. es ist absolut fantastisch dafür. Wenn Sie andererseits eine Sprache wünschen, die mit Ihnen wächst, wenn Sie mehr tun möchten, kann ich Python oder Ruby vorschlagen.

Wie auch immer, viel Glück!

16
MattG

Ich schlage das großartige Online-Buch Dive Into Python vor. So habe ich die Sprache ursprünglich gelernt.

Neben dem Erlernen der Grundstruktur der Sprache und einer Vielzahl nützlicher Datenstrukturen enthält sie ein gutes Kapitel über Dateihandhabung und nachfolgende Kapitel über reguläre Ausdrücke und mehr.

9
Dan Lenski

Hinzufügen zu vorherigen Antworten: Überprüfen Sie das Modul pexpect für den Umgang mit interaktiven Befehlen (adduser, passwd usw.).

7

Ein Grund, warum ich Python) liebe, ist, dass es viel besser standardisiert ist als die POSIX-Tools. Ich muss doppelt und dreifach prüfen, ob jedes Bit mit anderen Betriebssystemen kompatibel ist. Ein Programm, das auf einem Linux-System geschrieben wurde funktioniert auf einem BSD-System von OSX möglicherweise nicht genauso. Mit Python muss ich nur überprüfen, ob das Zielsystem eine ausreichend moderne Version von Python hat.

Noch besser ist, dass ein in Standard Python geschriebenes Programm sogar unter Windows läuft!

7
Hal Canary

Ich werde hier meine Meinung basierend auf Erfahrung abgeben:

Für Shell:

  • Shell kann sehr leicht schreibgeschützten Code erzeugen. Schreiben Sie es und wenn Sie darauf zurückkommen, werden Sie nie wieder herausfinden, was Sie getan haben. Dies ist sehr einfach zu bewerkstelligen.
  • Shell kann VIELE Textverarbeitungen, Aufteilungen usw. in einer Zeile mit Pipes ausführen.
  • es ist die beste Klebesprache, wenn es darum geht, den Aufruf von Programmen in verschiedene Programmiersprachen zu integrieren.

Für Python:

  • wenn Sie Portabilität für Windows möchten, verwenden Sie Python.
  • python kann besser sein, wenn Sie nur mehr als nur Text bearbeiten müssen, z. B. eine Sammlung von Zahlen. Dafür empfehle ich Python.

Normalerweise wähle ich bash für die meisten Dinge, aber wenn ich etwas habe, das Fenstergrenzen überschreiten muss, verwende ich einfach Python.

6
Germán Diago

pythonpy ist ein Tool, das einfachen Zugriff auf viele der Funktionen von awk und sed bietet, jedoch mit python syntax:

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

Bei der Recherche zu diesem Thema habe ich diesen Proof-of-Concept-Code (über einen Kommentar unter http://jlebar.com/2010/2/1/Replacing_Bash.html gefunden ), mit dem Sie "Shell-ähnliche Pipelines in Python unter Verwendung einer knappen Syntax schreiben und vorhandene Systemtools nutzen können, wo sie sinnvoll sind":

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

Ich habe halblange Shell-Skripte (300-500 Zeilen) und Python Code mit ähnlichen Funktionen erstellt. Wenn viele externe Befehle ausgeführt werden, ist die Shell einfacher zu verwenden. Perl ist Auch eine gute Option, wenn viel Text bearbeitet wird.

3
Mike Davis

Ihre beste Wahl ist ein Tool, das speziell auf Ihr Problem zugeschnitten ist. Wenn es um die Verarbeitung von Textdateien geht, sind Sed, Awk und Perl die Top-Kandidaten. Python ist eine universelle dynamische Sprache. Wie bei jeder universellen Sprache gibt es Unterstützung für Dateimanipulationen, aber das ist nicht der eigentliche Zweck. Ich würde Python oder Ruby) in Betracht ziehen, wenn ich insbesondere eine dynamische Sprache benötigen würde.

Kurz gesagt, lernen Sie Sed und Awk wirklich gut, plus all die anderen Extras, die mit Ihrem Geschmack von * nix kommen (all die eingebauten Bash-Funktionen, grep, tr und so weiter) Textdatei-Verarbeitung, an der Sie interessiert sind, Sie verwenden bereits das richtige Material.

2
Eric Smith

Sie können python anstelle von bash mit der Bibliothek ShellPy verwenden.

Hier ist ein Beispiel, das den Avatar des Benutzers Python von Github herunterlädt:

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')

Wie Sie sehen, werden alle Ausdrücke innerhalb des Symbols mit dem gravierenden Akzent (`) in Shell ausgeführt. Und im Python Code können Sie die Ergebnisse dieser Ausführung erfassen und Aktionen ausführen. Zum Beispiel:

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

Diese Zeile führt zuerst git log --pretty=oneline --grep='Create' in der Shell und weisen Sie das Ergebnis der Protokollvariablen zu. Das Ergebnis hat folgende Eigenschaften:

stdout der gesamte Text vom stdout des ausgeführten Prozesses

stderr Der gesamte Text aus stderr des ausgeführten Prozesses

Rückkehrcode Rückkehrcode der Ausführung

Dies ist eine allgemeine Übersicht über die Bibliothek, eine detailliertere Beschreibung mit Beispielen finden Sie hier .

2

Ich habe ein Paket auf PyPI veröffentlicht: ez .
Verwenden Sie pip install ez, Um es zu installieren.

Es hat allgemeine Befehle in Shell gepackt und meine Bibliothek verwendet im Grunde die gleiche Syntax wie Shell. Beispielsweise kann cp (Quelle, Ziel) sowohl Dateien als auch Ordner verarbeiten! (Wrapper von shutil.copy shutil.copytree und entscheidet, wann welches verwendet wird). Noch schöner kann es Vektorisierung wie R unterstützen!

Ein weiteres Beispiel: no os.walk. Verwenden Sie fls (path, regex), um Dateien rekursiv zu suchen und mit regulären Ausdrücken zu filtern. Es wird eine Liste von Dateien mit oder ohne vollständigen Pfad zurückgegeben

Letztes Beispiel: Sie können sie kombinieren, um sehr einfache Skripte zu schreiben:
files = fls('.','py$'); cp(files, myDir)

Probieren Sie es auf jeden Fall aus! Es hat mich Hunderte von Stunden gekostet, es zu schreiben/zu verbessern!

1
Jerry T

Wenn Ihre Textdatei-Manipulation normalerweise einmalig ist, möglicherweise auf der Shell-Eingabeaufforderung, erhalten Sie von Python nichts Besseres.

Auf der anderen Seite ist python ist großartig - und Sie können Erstellen Sie ganz einfach Ihre eigenen Bibliotheken (das können Sie auch mit Shell-Skripten tun, aber es ist umständlicher).

Ein sehr einfaches Beispiel, um ein Gefühl zu bekommen.

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

Überprüfen Sie auch sys und getopt, sie sind die ersten, die Sie benötigen.

1
Davide