2016-11-18 79 views
2

我需要从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

@Sundeep数字列表看起来不是范围'128082 + 5000 = 133082',而不是用户发布的数字:159845。 – sorontar

+0

@sorontar,true ..问题不清楚..但我认为OP想要一个范围(不管那可能是什么) – Sundeep

+0

为什么你有尾随'; d'?那么'sed -n'128082,133082p; 133083q'file> out'呢?祝你好运。 – shellter

回答

3

提示的帽子Jonathan Leffler他的帮助的。

它看起来像如在MacOS使用(如MACOS 10.12.1的)BSD sed具有上的脚本可以传递给它的每个线的大小的硬限制:2048字节

当作为命令行参数(隐含的第一个操作数,或者通过明确的选项-e)通过,脚本通常通过为线,像你一样。

如果一行变得很长,这是令人遗憾的是盲目的切断,通常导致看似随机的语法错误,就像你看到的一个。

有两种变通方法

  • 确保你的脚本只包含短足够线通过分离命令与\n(新行),而不是;和/或跨多个分割你的脚本-e选项(这很麻烦)。

  • 经由文件提供整个脚本,使用-f选项,在这种情况下,所有命令必须\n而非;反正分离。
    如果您的脚本太长而无法安装在单个命令行上(由系统施加的限制 - 请参阅底部),使用-f是您唯一的选择。


这里有一个命令行脚本示例太长:

$ sed -n "$(printf '%sp;' {1..432})" <<<'line 1' 
sed: 1: "1p;2p;3p;4p;5p;6p;7p;8p ...": command expected # !! ERROR 

即使脚本语法正确,削减其唯一在2048字节叶线,关闭它不正确,导致看似随机的command expected错误。

在这种情况下,各地限制的工作很简单:用\n更换;,各条线变短足:

$ sed -n "$(printf '%sp\n' {1..432})" <<<'line 1' 
line 1 # OK 

既然你已经有行号的文件 - line_file - 你可以使用辅助sed命令从它创建\n - 分隔脚本:

$ sed -n "$(sed 's/$/p/' line_file)" file > output 

以下是如何通过一个脚本文件通过-f过去了,其中的命令是\n - 分隔修复该问题解决的问题:

$ 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 

注:使用进程替换(sed -n -f <(printf ...) ...)作为一个特别的脚本文件莫名其妙地不是工作。

另请注意,整体最大。用于调用macOS上的sed等外部实用程序的命令行长度(截至10.12)为262144(256 KB;由getconf ARG_MAX确定),并且实际上限制较低,因为环境变量块的大小播放角色。
但是,如果您达到此限制,则会收到更有用的错误消息:Argument list too long

+2

您的大小限制是我怀疑但不知道的,因为它处理较小的命令。 “sed -n”$(sed's/$/p /'line_file)“file> output”命令可以在不到一分钟的时间内运行。 1+也用于非常有用的解释。 – aish1249

相关问题