【问题标题】:using head -n1 to get first match of grep on osx使用 head -n1 在 osx 上获得 grep 的第一场比赛
【发布时间】:2018-02-20 18:52:21
【问题描述】:

我正在尝试使用 head -n1 来获得第一个 grep 匹配项(建议在几个地方使用)

我希望这会起作用

$ printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep -w 333 | head -n1

(将永远持续的内容输入到 grep 命令中,该命令将选择一行,然后从该输出中取出第一行)

但是,没有输出,而且永远不会停止。

这按预期工作:(取第一行无限输出,没有 grep)

$ printf "x=0;\nwhile True:\n x+=1\n print x" | python | head -n1
1
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>
IOError: [Errno 32] Broken pipe

这很有效:(grep 输出并得到一个匹配)

$ printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep -w 333
333

(并且永远不会退出)

但是,这种组合并没有达到我的预期:

$ printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep -w 333 | head -n1

(从不打印任何内容,从不退出)

【问题讨论】:

  • 顺便说一句,您可以使用 python -c $'x=0;\nwhile True:\n x+=1\n print x' 传递带有文字换行符的字符串作为参数(而不是标准输入)
  • 我很好奇 - 为什么要使用 shell 打印一个循环来管道到 python 执行而不是仅仅在 shell 中编写循环:x=0; while :; do echo $(( x+=1 )); done | grep ...?
  • 抱歉——我实际上并没有用那个 python 循环来做这个——只是用它作为一个永远持续下去的例子。尾随文件时也会发生同样的事情。

标签: bash macos grep head


【解决方案1】:

您需要在grep 中使用--line-buffered 选项:

printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep --line-buffered -w 333 | head -n 1
333

根据man grep

--line-buffered
     Force output to be line buffered.  By default, output is line buffered when standard
     output is a terminal and block buffered otherwise.

但请注意,由于您在 python 代码中运行无限循环,因此该命令不会退出。

如果您希望管道在打印第一个匹配项后立即退出,请使用 awk:

printf "x=0;\nwhile True:\n x+=1\n print x" | python |& awk '$1=="333"/{print; exit}'
333

【讨论】:

  • right printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep 333 --line-buffered | head -n1 打印结果,但仍然没有像你说的那样退出。我仍然不明白为什么printf "x=0;\nwhile True:\n x+=1\n print x" | python | head -n1 确实退出了,并且仍然有无限循环。
  • head -n 1 退出,因为它已经打印了给定数量的行,即1 行。但是grep 没有退出,因为我们没有告诉grep 在第一场比赛后退出。这可以使用awkgrep -m 1 来完成
  • 那为什么printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep 333 | head -n1 退出?
  • 这是因为grep缓冲行为。如果您使用printf "x=0;\nwhile True:\n x+=1\n print x" | python | awk '/333/' | head -n 1,则它不会挂起。
【解决方案2】:

BSD grep on macOS > 10.9 支持-m 选项:

-m num, --max-count=num
     Stop reading the file after num matches.

所以你可以跳过头部并使用-m1

$ printf "x=0;\nwhile True:\n x+=1\n print x" | python | grep -w 333 -m1
333
Traceback (most recent call last):
  File "<stdin>", line 4, in <module>

【讨论】:

    猜你喜欢
    • 2022-11-23
    • 2015-03-11
    • 1970-01-01
    • 1970-01-01
    • 2012-12-15
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多