从大文本文件中提取大量的行

时间:2016-11-18 02:42:21

标签: bash macos sed

我需要在bash(OSX)上从~300,000行的文件中提取~5000行。运行

sed '128082p;128083p;...(4996 numbers)....;159845q;d' file > output

给出错误

sed: 1: "128082p;128083p;128084p ...": command expected

如果我尝试仅提取10行,则同样的命令也可以。而运行

for i in `cat line_file`; do sed -n "$ip" file; done >> output

创建一个超过5000行的文件。在任何一种情况下,什么是正确的命令?

编辑:这不是一系列数字。

1 个答案:

答案 0 :(得分:3)

Jonathan Leffler寻求帮助的提示。

在macOS上使用的 BSD sed (从macOS 10.12.1开始)对每个行的大小硬限制 > 2048字节

当作为命令行参数(隐式地作为第一个操作数,或通过-e选项显式)传递时,脚本通常作为单个传递就像你一样。

如果单行太长,很遗憾地会盲目地切断,通常会导致看似随机的语法错误,就像你看到的那样。

有两个解决方法

  • 确保您的脚本只包含足够短的行,方法是将命令分隔为\n(换行符)而不是;和/或将您的脚本拆分为多个-e选项(这很麻烦)。

  • 使用-f选项通过文件提供整个脚本,在这种情况下,所有命令必须与{{1}分开而不是\n无论如何 万一您的脚本太长而无法放在一个命令行上(系统强加的限制 - 见底部),使用;是您唯一的选择。

以下是一个太长的命令行脚本示例:

-f

尽管脚本在语法上是正确的,但是在2048字节处切断其中一个并且只有一行是不正确的,这会导致看似随机的$ sed -n "$(printf '%sp;' {1..432})" <<<'line 1' sed: 1: "1p;2p;3p;4p;5p;6p;7p;8p ...": command expected # !! ERROR 错误。

在这种情况下,解决限制很简单:将command expected替换为;,单个行变得足够短:

\n

由于您已有行号的文件 - $ sed -n "$(printf '%sp\n' {1..432})" <<<'line 1' line 1 # OK - 您可以使用辅助 line_file命令创建{{1分离的脚本:

sed

以下是如何通过\n传递的脚本文件解决问题,其中命令为 $ sed -n "$(sed 's/$/p/' line_file)" file > output - 分开修复问题:

-f

注意:使用流程替换(\n)作为临时脚本文件莫名其妙地工作。

另请注意整体最大值。在macOS上调用外部实用程序(如10.12)的命令行的长度为$ printf '%sp\n' {1..432} > script.sed # Create script file with \n-separated commands. $ sed -n -f "script.sed" <<<'line 1' # Pass script file via -f line 1 # OK (256 KB;由sed -n -f <(printf ...) ...确定),实际上限制较低,因为环境变量块的大小起作用 但是,如果您达到此限制,则会收到更有用的错误消息:sed