我需要在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行的文件。在任何一种情况下,什么是正确的命令?
编辑:这不是一系列数字。
答案 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
。