【问题标题】:Use python in shell, as if it were awk在 shell 中使用 python,就好像它是 awk
【发布时间】:2014-11-09 12:36:47
【问题描述】:

假设我想在标准输出上print 1 + 1(即单线编码)。

有了awk,我可以简单地做到:

$ echo | awk '{print 1+1}'
2

如何用 python 做到这一点?

【问题讨论】:

  • 有了awk,你就不需要echo。使用BEGINawk 'BEGIN{print 1+1}'
  • 请注意,Python 对单行代码的用处不如awk... 但它对例如 5 行代码更有用,因此您倾向于看到它与 HEREdoc 脚本一起使用不仅仅是内联脚本。 (但您可以将它用于内联脚本,如 IfLoop 的回答所示。)
  • @chepner 您能否详细说明为什么ENDBEGIN 更有效? AFAIK 都只运行一次,前者在读取输入之后,前者在读取输入之前。
  • @jaypal 不是;我在看到你的出现之前发表了我的评论,只是碰巧使用了END 而不是BEGIN。 “更高效”只是指忽略(空)标准输入,而不是启动第二个进程来提供无论如何都会被忽略的输入,而不是在BEGINEND 之间进行选择。
  • @Cawas:Python 被明确设计为重视可读性而不是简洁性和明确性而不是隐性。你可以塞进一条线上的东西是有限度的。在 awk(或 sed 或 perl)中是语法的东西是 Python 中的词汇,甚至可能不是内置的;标准输入或命令行参数之类的东西几乎没有什么魔力;等等。所以不,Python 永远不会像 awk 一样有用。

标签: python shell awk


【解决方案1】:

你正在寻找-c:

$ python -c 'print 1 + 1'
2

【讨论】:

  • 这里不需要echo hello |awk 只需要它,因为它对输入行进行操作。
  • @bgbg:Python 对标准输入没有任何作用;如果需要,您必须显式调用input,或者循环访问sys.stdinfileinput.input()
  • @bgbg awk 隐式循环其标准输入,因此BEGINEND 分别用于在读取输入之前和之后执行代码。相反,Python 会忽略其标准输入,除非您的代码专门从中读取。
  • 原因我改变了接受的答案:这完全解决了我的例子,但实际上它没有回答我的问题“python 好像它是 awk”。起初我虽然会这么简单,但事实并非如此:stackoverflow.com/questions/2043453/…
【解决方案2】:

正如 ifLoop 指出的那样,您在这里寻找的是-c

但是,正如您所发现的,python -c 通常不如对应的awk(或sedbashperl 甚至ruby)用于单行。

Python 被明确地设计为重视可读性而不是简洁性和明确性而不是隐含性(以及一些相关的权衡,例如词汇而不是语法,尽可能少的魔法等等)。见the Zen of Python。您可以在一行中塞进什么内容是有意限制的,并且必须使用 sys.stdinsys.argvfileinput.input() 明确地完成循环标准输入和/或命令行参数之类的事情。

这意味着在 Python 中编写一些非常琐碎的脚本变得不那么琐碎了,但这被认为是一个很好的折衷方案,可以让即使是不太琐碎的脚本也更容易编写、维护和理解。

核心开发人员明白这意味着您无法在 Python 中重写大量单行代码。如果你问他们,他们中的大多数人会问为什么这是一个问题。

如果您知道如何用sedawk 之类的语言将其编写为单行,那么您应该将其编写为sedawk 的单行。这些都是非常好的语言,对于各种简单的任务都很方便,没有理由仅仅因为 Python 也是一门好语言而避免使用它们。

如果您无法通过语法来编写该单行...那么,它可能不应该是单行。您想在 Python 中尝试它的唯一原因是 Python 通常更易于编写和阅读,同样的原因与 Python 不会让您在没有 3 行的情况下编写您想要的内容的原因相同。所以只写3行。 Python 非常适合。

所以,你经常真正想要的不是-c,而是heredoc,或者只是一个像其他程序一样运行的单独脚本,或者awkperl而不是python

【讨论】:

  • 我认为很多人不关心学习越来越多的语言。我提出问题的最大原因是我的兄弟在 cisco 和其他东西上工作,所以他知道如何外壳,但他不是程序员,也不想成为。他只是想学习如何编程来简化他的生活,因此,Python 比awksed 具有更高的潜力(sed 甚至不是一种语言)......无论如何,这可能应该继续下去到论坛或只是到另一个问题!一旦我弄清楚,我会链接。 :P
  • @Cawas:awk 之类的优势之一是,您可以教人们做简单的事情,而不会让他们意识到他们正在学习编程……但是,是的,我明白你的观点如果我们有一种适合所有事情的语言,或者至少适合非专业程序员类型可能想做的所有事情,那就太好了。也许在 Python 之上构建一个 shell,而不是让 Python 从 shell 中更有用?但我看到有人尝试用 C/Cint、emacs-lisp、Tcl 等来做这件事,但总体来说效果并不好……无论如何,有机会我会去论坛看看……跨度>
【解决方案3】:

如果你在 shell 中,下一个是基本整数数学

echo $((1+1))
echo $(( 100 / 5 ))

等等……

对于浮点,是的,你应该使用awk,或bc,或dc,或任何其他知道浮点数学的语言......

另外,请阅读:https://stackoverflow.com/a/450853/632407

【讨论】:

    【解决方案4】:

    受到answer by IfLoop 的启发,我想知道awk 中方便的BEGINEND 块。我找到了pawk module

        ls -l | awk 'BEGIN {c = 0} {c += $5} END {print c}'
        ls -l | pawk -s -B 'c = 0' -E 'c' 'c += int(f[4])'
    

    看起来很有希望,但我从未尝试过(还)

    【讨论】:

    • 那个爪子看起来很有趣!我喜欢 Python,但我经常发现自己因为一些小事情而回到 awk,因为命令行中的多行 Python 相当乏味。
    • @PM2Ring:小事恢复到 awk 没问题。或者 sed、grep、bash 本身……在某些情况下甚至可能是 perl(只要你不告诉任何人)。
    • 有时,bash 比 Python 更有意义,但它可能非常烦人,尤其是在处理包含空格和其他垃圾的文件名时。我经常使用 grep,通常在 ls 输出上执行正则表达式,或者搜索我的 *.py 文件。多年前,我在 awk 中编写了一个 HTML 解析器(用于非常固定格式的 HTML),但我不会再匆忙这样做了。 :) 当我学习 sed 时,我写了一个递增整数的 sed 脚本,但它并不漂亮。 :)
    【解决方案5】:

    就像SingleNegationElimination's 回答推荐的一样,-c 标志是适合这项工作的工具。

    以下是一些使用 awk、ruby 和 python 的示例:

    echo foo bar baz | awk '{ split($0, arr, " "); print arr[NF] }'
    baz
    echo foo bar baz | ruby -e 'puts STDIN.read.chomp.split(" ")[-1]'
    baz
    echo foo bar baz | python -c 'import sys; print sys.stdin.read().rstrip().split(" ")[-1]'
    baz
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 2021-06-27
    • 1970-01-01
    相关资源
    最近更新 更多