如何在Python中实现常见的bash习惯用法?
我现在处理文本文件主要是用一些记得不太清楚的AWK、sed、Bash,还有一点点Perl。
我在一些地方看到有人说Python在这方面很不错。那么我该怎么用Python来替代这些Shell脚本、AWK、sed等呢?
17 个回答
我刚刚发现了如何把bash和ipython的优点结合起来。到目前为止,这对我来说比使用subprocess等方法要舒服多了。你可以轻松地复制现有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 ;)
每个命令行都有几个功能集。
基本的Linux/Unix命令。这些命令都可以通过subprocess库来使用。不过,这并不总是执行所有外部命令的最佳选择。你还可以看看shutil,它提供了一些独立的Linux命令,但你也可以直接在Python脚本中实现。还有一大堆Linux命令在os库中;用Python来做这些会更简单。
而且——额外的好处!——速度更快。每个独立的Linux命令在命令行中(有一些例外)都会启动一个子进程。通过使用Python的
shutil
和os
模块,你就不需要启动子进程了。命令行环境功能。这包括设置命令环境的东西(当前目录、环境变量等等)。你可以直接在Python中轻松管理这些。
命令行编程功能。这包括所有的进程状态码检查、各种逻辑命令(if、while、for等)、测试命令及其相关命令,还有函数定义的内容。这些在Python中都简单得多。这是用Python替代bash的一个巨大胜利。
交互功能。这包括命令历史等。写命令行脚本时不需要这个。这只是为了人机交互,而不是为了写脚本。
命令行文件管理功能。这包括重定向和管道。这部分比较复杂。很多操作可以用subprocess来完成。但在Python中,有些在命令行中简单的事情就不太好处理。比如
(a | b; c ) | something >result
。这个命令会并行运行两个进程(a
的输出作为b
的输入),然后再运行第三个进程。这个序列的输出会与something
并行运行,最后输出会收集到一个名为result
的文件中。在其他语言中表达这些就比较复杂。
一些特定的程序(比如awk、sed、grep等)通常可以重写成Python模块。但不要过于追求完美。替换你需要的部分,逐步完善你的“grep”模块。不要一开始就写一个完全替代“grep”的Python模块。
最好的事情是你可以分步骤进行。
- 用Python替换AWK和PERL。其他的先不动。
- 考虑用Python替换GREPP。这可能会复杂一些,但你可以根据自己的处理需求来定制你的GREPP版本。
- 考虑用Python循环和
os.walk
替换FIND。这是一个很大的胜利,因为你不需要启动那么多进程。 - 考虑用Python脚本替换常见的命令行逻辑(循环、决策等)。