【发布时间】:2015-02-28 11:03:35
【问题描述】:
我有一个包含将近 5*(10^6) 行整数的文件。所以,我的文件足够大。
问题是关于提取特定行,按条件过滤它们。 例如,我想:
- 提取前 N 行而不读取整个文件。
- 提取数字小于或等于 X(或 >=、)的行
- 提取与数字相关的
condition行(数学谓词)
有没有更巧妙的方法来执行这些任务? (使用sed 或awk 或cat 或head)
提前致谢。
【问题讨论】:
我有一个包含将近 5*(10^6) 行整数的文件。所以,我的文件足够大。
问题是关于提取特定行,按条件过滤它们。 例如,我想:
condition 行(数学谓词)有没有更巧妙的方法来执行这些任务? (使用sed 或awk 或cat 或head)
提前致谢。
【问题讨论】:
要提取第一行$NUMBER,
head -n $NUMBER filename
假设每一行只包含一个数字(尽管如果第一个标记是一个也可以),2 可以这样解决:
awk '$1 >= 1234 && $1 < 5678' filename
本着精神,3 只是扩展
awk 'condition' filename
不过,如果您指定 condition 应该是什么,那将会有所帮助。这样,您必须阅读 awk 文档以了解如何对其进行编码。同样,该数字将由$1 表示。
我想我无法解释有关head 电话的任何内容,这实际上就是它在锡上所说的内容。至于awk 行:awk 和sed 一样,按行工作。 awk 在循环中获取行并将您的代码应用于每一行。此代码采用以下形式
condition1 { action1 }
condition2 { action2 }
# and so forth
对于 awk 获取的每一行,条件按照它们出现的顺序进行检查,如果条件为真,则执行与每个条件相关的操作。例如,可以使用 awk 提取文件的前 $NUMBER 行,如下所示:
awk -v number="$NUMBER" '1 { print } NR == number { exit }' filename
其中1 是true 的同义词(如在C 中),NR 是行号。 -v 命令行选项将 awk 变量 number 初始化为 $NUMBER。如果未指定任何操作,则默认操作为{ print },它将打印整行。所以
awk 'condition' filename
是简写
awk 'condition { print }' filename
...打印条件成立的每一行。
【讨论】:
awk 命令。
-v 选项将 shell 变量传输到 awk。解释中的例子可以写成awk -v number=$NUMBER '1 { print } NR == number { exit }' filename。想一想,这样做实际上是更好的风格,因为将 shell 变量直接替换到代码中会导致奇怪。例如,如果$NUMBER 是10 { print } 0,则代码将完全改变。我想我会在答案中改变它,所以没有人最终会模仿它。
$1。你可以在任何地方写\$1,但最好使用-v。
RS 值的多行文本块。 2) 切勿在 UNIX 上将 awk 脚本用双引号括起来,请参阅 cfajohnson.com/shell/cus-faq-2.html#Q24 了解如何将 shell 变量的值传递给 awk 脚本。 3) 总是引用 shell 变量,所以它的 number="$NUMBER"。 4) 按照惯例,为导出的 shell 变量保留全大写。