私は現在、よく覚えていないAWK、sed、Bash、およびほんの少しのPerlを使用してテキストファイルを操作しています。
私はpythonがこの種のことのために良いいくつかの場所について言及するのを見ました。Pythonを使用して、シェルスクリプト、AWK、sedなどを置き換えるにはどうすればよいですか?
私は現在、よく覚えていないAWK、sed、Bash、およびほんの少しのPerlを使用してテキストファイルを操作しています。
私はpythonがこの種のことのために良いいくつかの場所について言及するのを見ました。Pythonを使用して、シェルスクリプト、AWK、sedなどを置き換えるにはどうすればよいですか?
回答:
どのシェルにもいくつかの機能セットがあります。
Essential Linux / Unixコマンド。これらはすべてサブプロセスライブラリから利用できます。これは、すべての外部コマンドを実行するための最良の最初の選択肢とは限りません。個別の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
。多くのプロセスを生成しないので、これは大きな勝利です。find
が持っているいくつかのスクリプトのpythonバージョンは、醜くて長く、比較してメンテナンスができないため、@ EvanPlaiceに同意しません。多くのものはシェルスクリプトであるべきで、他のものはそうではありません。すべてがPythonまたはBASH(またはその他)の1つだけである必要はありません。
(a | b; c ) | something >result
)、ややそれがシェルのパイプラインを通過する自明容易であることによって緩和されるsubprocess
方法を用いてshell=True
私は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ドキュメントを参照してください。
filelines = ! cat myfile
$var
、シェルコマンドのようにPython変数を使用できますか?ワオ。これは受け入れられる答えになるはずです。
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
引き続き正常に動作します。
チュートリアルは非常に長く、誰かが通常ashまたはbashプロンプトで期待する機能のかなりの部分をカバーしているようです:
?
&??
*.xsh
インポート可能なコマンドやスクリプトを実行します${}
$()
でキャプチャされていないサブプロセス$[]
、Pythonで評価@()
*
または正規表現ファイル名グロブバックバック.xsh
:xonshコードでファイルの拡張子をgithub.com/xonsh/xonsh/issues/2478。それ以外の場合はevalx
、.py
ファイルから直接呼び出すために使用する必要があります。
初めに、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)
あなたの最善の策は、特にあなたの問題に向けられたツールです。テキストファイルを処理する場合、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')
ご覧のとおり、アクサングラーブ( `)記号内のすべての式はシェルで実行されます。また、Pythonコードでは、この実行の結果をキャプチャして、アクションを実行できます。例えば:
log = `git log --pretty=oneline --grep='Create'
この行は最初git log --pretty=oneline --grep='Create'
にシェルで実行され、次にその結果がログ変数に割り当てられます。結果には次のプロパティがあります。
標準出力に実行される処理の標準出力からテキスト全体を
標準エラー出力実行プロセスの標準エラー出力からテキスト全体を
実行のreturncode returncode
これはライブラリの一般的な概要であり、例を含むより詳細な説明はここにあります。
テキストファイルの操作が通常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モジュールも確認してください。これらが最初に必要になります。
PyPI:ezでパッケージを公開しました。インストールに
使用pip install ez
します。
シェルには一般的なコマンドがパックされており、私のライブラリは基本的にシェルと同じ構文を使用しています。たとえば、cp(source、destination)はファイルとフォルダの両方を処理できます!(shutil.copyのラッパーshutil.copytreeは、どれを使用するかを決定します)。さらに美しく、Rのようなベクトル化をサポートできます。
別の例:os.walkを使用せず、fls(path、regex)を使用して再帰的にファイルを検索し、正規表現でフィルタリングすると、フルパスの有無にかかわらずファイルのリストが返されます
最後の例:それらを組み合わせて非常に単純なスクリプトを書くことができます:
files = fls('.','py$'); cp(files, myDir)
ぜひチェックしてください!それを書いたり改善したりするのに何百時間も費やしました!