現在、テキストファイルの操作は、覚えの悪いAWK、sed、Bash、およびごく一部のPerlを使用して行っています。
私はpythonがこの種のものに適しているといういくつかの場所に言及しているのを見ました。 Pythonを使用して、シェルスクリプト、AWK、sed、およびフレンドを置き換えるにはどうすればよいですか?
シェルにはいくつかの機能セットがあります。
Essential Linux/Unixコマンド。これらはすべて subprocess ライブラリから利用できます。これは、all外部コマンドを実行するための常に最良の最初の選択肢とは限りません。個別のLinuxコマンドである一部のコマンドについては shutil もご覧ください。ただし、Pythonスクリプトに直接実装することもできます。 Linuxコマンドの別の巨大なバッチは os ライブラリにあります。これらはPythonでより簡単に行うことができます。
そして、ボーナス! -より迅速に。シェル内の個別のLinuxコマンド(いくつかの例外を除く)は、サブプロセスをフォークします。 Python shutil
およびos
モジュールを使用することにより、サブプロセスをフォークしません。
シェル環境機能。これには、コマンドの環境を設定するもの(現在のディレクトリと環境変数、その他)が含まれます。これはPythonから直接簡単に管理できます。
シェルプログラミング機能。これはすべて、プロセスステータスコードのチェック、さまざまなロジックコマンド(if、while、forなど)、テストコマンド、およびそのすべての関連コマンドです。関数定義のもの。これはすべてPythonではるかに簡単です。これは、bashを削除してPythonで実行した場合の大きな勝利の1つです。
インタラクション機能。これには、コマンド履歴とその他が含まれます。シェルスクリプトを記述するためにこれは必要ありません。これは人間の相互作用のためだけであり、スクリプト作成のためではありません。
シェルファイル管理機能。これには、リダイレクトとパイプラインが含まれます。これは難しいです。この多くはサブプロセスで実行できます。しかし、シェルで簡単に実行できることは、Pythonでは不快です。特に(a | b; c ) | something >result
のようなもの。これは、2つのプロセスを並行して実行し(a
の出力をb
への入力として)、続いて3番目のプロセスを実行します。そのシーケンスからの出力はsomething
と並行して実行され、出力はresult
という名前のファイルに収集されます。他の言語で表現するのは複雑です。
特定のプログラム(awk、sed、grepなど)は、多くの場合Pythonモジュールとして書き換えることができます。船外に出ないでください。必要なものを置き換えて、「grep」モジュールを進化させます。 「grep」を置き換えるPythonモジュールを書くことから始めないでください。
最も良いのは、これを段階的に実行できることです。
os.walk
を使用するPythonループに置き換えることを見てください。プロセスをそれほど多く生成しないので、これは大きな勝利です。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ドキュメントを参照してください。
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
それでも正常に動作します。
チュートリアルは非常に長く、一般にアッシュまたはバッシュプロンプトで期待される機能の多くをカバーしているようです。
?
および??
のヘルプとスーパーヘルプ*.xsh
スクリプトを実行します${}
を使用したルックアップを含む環境変数$()
でキャプチャされたサブプロセス、$[]
でキャプチャされていないサブプロセス、@()
で評価されたPython*
を使用したファイル名のグロビング、またはバックティックを使用した正規表現のファイル名のグロビング最初はsh、sed、awk(およびfind、grep、...)がありました。良かったです。しかし、awkは奇妙な小さな獣であり、頻繁に使用しないと覚えにくい場合があります。その後、偉大なラクダがPerlを作成しました。 Perlはシステム管理者の夢でした。ステロイドのシェルスクリプトのようでした。正規表現を含むテキスト処理は、言語の一部にすぎません。それからい...人々はPerlで大きなアプリケーションを作ろうとしました。誤解しないでください。Perlはアプリケーションになれますが、本当に注意しなければ混乱のように見えます(できます!)。次に、このフラットデータビジネスがすべてあります。プログラマーを動かすのに十分です。
Python、Rubyなどを入力してください。これらは本当に非常に優れた汎用言語です。それらはテキスト処理をサポートし、それをうまく行います(ただし、おそらく言語の基本的なコアと密接に結びついていません)。しかし、彼らはまた非常にうまくスケールアップし、一日の終わりにはまだ見栄えの良いコードを持っています。彼らはまた、ほとんどすべてのためにたくさんのライブラリを備えたかなり多額のコミュニティを開発しています。
今、Perlに対する否定的な点の多くは意見の問題であり、確かに一部の人々は非常にきれいなPerlを書くことができますが、この多くの人々は難読化されたコードを作成するのは簡単すぎると不平を言うので、あなたはいくらかの真実がそこにあることを知っています。質問は実際になります。単純なbashスクリプトの置換以上にこの言語を使用することはありますか。そうでない場合は、もう少しPerlを学んでください。それは絶対に素晴らしいことです。一方、もっとやりたいように成長する言語が必要な場合は、PythonまたはRubyをお勧めします。
いずれにせよ、幸運を祈ります!
素晴らしいオンラインブックDive Into Pythonをお勧めします。それは私が元々言語を学んだ方法です。
以前の回答に追加:インタラクティブコマンド(adduser、passwdなど)を処理するための pexpect モジュールを確認します
Pythonが好きな理由の1つは、POSIXツールよりもはるかに標準化されていることです。各ビットが他のオペレーティングシステムと互換性があることを二重および三重チェックする必要があります。 Linuxシステムで作成されたプログラムは、OSXのBSDシステムでも同じように動作しない場合があります。 Pythonでは、ターゲットシステムに十分に新しいバージョンのPythonがあることを確認するだけです。
さらに良いことに、標準のPythonで書かれたプログラムはWindowsでも実行できます!
ここで、経験に基づいて私の意見を述べます。
シェルの場合:
Pythonの場合:
私は通常、ほとんどのことでbashを選択しますが、ウィンドウの境界を越える必要があるものがある場合は、Pythonを使用します。
pythonpy は、awkおよびsedの多くの機能に簡単にアクセスできるツールですが、python構文を使用します。
$ echo me2 | py -x 're.sub("me", "you", x)'
you2
このトピックの調査中に、私は この概念実証コード を見つけました( 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)
セミロングシェルスクリプト(300〜500行)と、同様の機能を実行するPythonコードを作成しました。多くの外部コマンドが実行されているとき、シェルの方が使いやすいと思います。 Perlは、多くのテキスト操作がある場合にも適したオプションです。
あなたの最善の策は、あなたの問題に特化したツールです。テキストファイルを処理している場合は、Sed、Awk、Perlが最有力候補です。 Pythonは汎用動的言語です。あらゆる汎用言語と同様に、ファイル操作のサポートがありますが、それはコアの目的ではありません。特に動的言語の要件がある場合は、PythonまたはRubyを検討します。
要するに、SedとAwkに加えて、* nix(Bashのすべてのビルトイン、grep、trなど)のフレーバーに付属する他のすべてのグッズをよく学んでください。興味のあるテキストファイル処理であれば、すでに適切なものを使用しています。
ShellPy ライブラリでは、bashの代わりにpythonを使用できます。
GithubからPythonユーザーのアバターをダウンロードする例を次に示します。
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')
ご覧のとおり、Graveアクセント( `)シンボル内のすべての式はシェルで実行されます。また、Pythonコードでは、この実行の結果をキャプチャし、アクションを実行できます。例えば:
log = `git log --pretty=oneline --grep='Create'
この行は、最初にシェルでgit log --pretty=oneline --grep='Create'
を実行してから、結果をログ変数に割り当てます。結果には次のプロパティがあります。
stdout実行されたプロセスのstdoutからのテキスト全体
stderr実行されたプロセスのstderrからのテキスト全体
returncode実行のリターンコード
これはライブラリの一般的な概要です。詳細な説明と例は here にあります。
PyPIでパッケージを公開しました: ez 。pip install ez
を使用してインストールします。
シェルには一般的なコマンドが詰め込まれており、私のlibは基本的にシェルと同じ構文を使用しています。たとえば、cp(source、destination)はファイルとフォルダーの両方を処理できます! (shutil.copy shutil.copytreeのラッパーで、いつどれを使用するかを決定します)。さらにうまく、Rのようなベクトル化をサポートできます!
別の例:os.walkなし、fls(path、regex)を使用してファイルを再帰的に検索し、正規表現でフィルター処理し、フルパスの有無にかかわらずファイルのリストを返します
最後の例:これらを組み合わせて、非常に単純なスクリプトを作成できます。files = fls('.','py$'); cp(files, myDir)
間違いなくチェックしてください!書く/改善するのに何百時間もかかりました!
テキストファイルの操作が通常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モジュールもチェックしてください。最初に必要です。