【发布时间】:2012-01-13 06:33:19
【问题描述】:
我需要在我的搜索字符串上方提取一行(例如,上面的 19 行)。通常情况下,我会选择
grep -B 19 $search_string $file | ...further processing
不过,该脚本也可以在 Solaris 上使用,其中 grep 不提供 -B 选项。通常,如果我知道前面的几行,我可以使用awk '/begin/,/end/' 打印一堆行。在这种特殊情况下,这是不可能的。我尝试了以下方法:
1) 环形缓冲溶液。
#!/bin/bash
g_a_buffer=( 0 )
g_i_buffer_index=1
while read line
do
g_a_buffer[$((g_i_buffer_index % 20))]=$line
echo $line|grep $search_string > /dev/null
[ $? -eq 0 ] && echo ${g_a_buffer[$(( (g_i_buffer_index + 2) % 20))]}
let "g_i_buffer_index += 1"
done < $file_name
这是非常慢。大约 40k 行需要 1m37s(grep 需要 0.005s)
2) awk 解决方案。我必须直截了当地说,我是 awk 的极端初学者,很少超越 awk '{print $1}'。 以下行不起作用,但可以让您了解我想要实现的目标:
awk '/mySearchString/ {print NR-19}' filename.txt
0.118s执行,速度不错!但我得到的只是一个行号 - 19。我需要的是位于 (line - 19) 的行的打印输出。经过一番谷歌搜索后,我仍然找不到答案。我承认这一定是一个非常基本的问题,但我似乎在这里碰壁了。
到目前为止,我发现的只是如何使用 awk 打印前一行(这是一种 1 行缓冲区),或者使用环形缓冲区但在 awk 中的大规模实现。有没有更优雅的方法来做到这一点?
感谢您的帮助!
【问题讨论】:
-
grep通常是一个与 bash 不同的程序,许多 Solaris 上的人只是在备用路径 (/opt/gnu) 中安装 GNU 工具(如 grep)以补充他们古老的 Sun 变体。在您的情况下可能会更有效。 -
Thiton,不幸的是这是不可能的,我必须处理可用的东西。
-
Derobert:这就是语义发挥作用的地方——perl 肯定可以在相关的 Solaris 服务器上使用,但我对 perl 的经验完全为零。所以是的,我可以,但我不能 :) 我将使用您的解决方案与下面的
grep -n一起运行,谢谢!