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?
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.
os.walk
Verwenden. Dies ist ein großer Gewinn, da Sie nicht so viele Prozesse erzeugen.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.
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 .
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:
?
& ??
*.xsh
- Skripte aus, die auch importiert werden können${}
$()
, Nicht erfasster Unterprozess mit $[]
, Python Auswertung mit @()
*
Oder Dateiname mit regulären Ausdrücken mit BackticksAm 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!
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.
Hinzufügen zu vorherigen Antworten: Überprüfen Sie das Modul pexpect für den Umgang mit interaktiven Befehlen (adduser, passwd usw.).
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!
Ich werde hier meine Meinung basierend auf Erfahrung abgeben:
Für Shell:
Für Python:
Normalerweise wähle ich bash für die meisten Dinge, aber wenn ich etwas habe, das Fenstergrenzen überschreiten muss, verwende ich einfach Python.
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
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)
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.
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.
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 .
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!
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.