我目前通过一堆不好记的AWK、sed、Bash和一小部分Perl来做我的文本文件操作。

我已经看到提到的一些地方,python很适合做这种事情。我如何使用Python来代替shell脚本,AWK, sed和朋友?


当前回答

以下是我的一些经验之谈:

外壳:

Shell可以很容易地生成只读代码。把它写下来,当你回头看的时候,你永远也不会知道你又做了什么。这很容易做到。 shell可以用管道在一行中做大量的文本处理、分割等。 当涉及到集成不同编程语言的程序调用时,它是最好的粘合语言。

python:

如果你想要Windows的可移植性,请使用python。 当您必须处理的不仅仅是文本,比如数字的集合时,Python可能会更好。为此,我推荐python。

我通常选择bash来处理大多数事情,但当我有一些必须跨越窗口边界的东西时,我就使用python。

其他回答

在ShellPy库中可以使用python而不是bash。

下面是一个从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重音(')符号内的表达式都在shell中执行。在Python代码中,您可以捕获此执行的结果并对其执行操作。例如:

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

这一行首先在shell中执行git log——pretty=oneline——grep='Create',然后将结果赋值给log变量。结果具有以下属性:

从已执行进程的Stdout中Stdout整个文本

Stderr从已执行进程的Stderr得到的整个文本

Returncode执行的返回码

这是该库的总体概述,更详细的描述和示例可以在这里找到。

截至2015年和Python 3.4的发布,现在有一个相当完整的用户交互shell: http://xon.sh/或https://github.com/scopatz/xonsh

演示视频没有显示正在使用的管道,但是在默认shell模式下支持管道。

Xonsh(“conch”)非常努力地模仿bash,因此您已经获得了肌肉记忆,例如

env | uniq | sort -r | grep PATH

or

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

仍然可以正常工作。

本教程相当冗长,似乎涵盖了人们通常在ash或bash提示符时所期望的大量功能:

Compiles, Evaluates, & Executes! Command History and Tab Completion Help & Superhelp with ? & ?? Aliases & Customized Prompts Executes Commands and/or *.xsh Scripts which can also be imported Environment Variables including Lookup with ${} Input/Output Redirection and Combining Background Jobs & Job Control Nesting Subprocesses, Pipes, and Coprocesses Subprocess-mode when a command exists, Python-mode otherwise Captured Subprocess with $(), Uncaptured Subprocess with $[], Python Evaluation with @() Filename Globbing with * or Regular Expression Filename Globbing with Backticks

我刚刚发现了如何结合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 ;)

请参阅IPython文档,了解系统shell命令并将其用作系统shell。

Pythonpy是一个工具,可以方便地访问awk和sed的许多特性,但使用python语法:

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

添加到前面的答案:检查pexpect模块处理交互式命令(adduser, passwd等)