1

我正在从网络中提取大量数据并过滤fooand bar,例如

for i in example.com example.org example.net
do
     echo "Data from $i"
     curl $i/data.csv | grep --after-context=3 "foo|bar"
done

每次foo出现,我都需要看接下来的几行(grep --after-context=3),但是当bar出现时,我只需要那一行。

是否可以使其在单个grep, sed, awk(或其他标准 unix)命令中工作?

4

3 回答 3

4

单程:

curl .... | awk  '/foo/{x=NR+3}(NR<=x) || /bar/'

当遇到 foo 时,x 设置为当前行号 + 3,因此条件(NR+x)使行“foo”和接下来的 3 行被打印。/bar/使包含bar打印的行。

于 2013-07-26T11:44:05.013 回答
1
awk 'BEGIN {np=0} /bar/ {print; next} /foo/ {np=1;ln=RN;print;next} ln!=0 && RN>(ln+3) {np=0;ln=0} np==1 {print}' INPUTFILE

而不是grep,您可以使用上面的。它能做什么:

  1. inBEGIN设置非打印变量。
  2. /bar/ {print}如果您无法弄清楚,那么...(next用于跳过所有其他规则并移至下一条记录)。
  3. /foo/ {np=1;ln=RN;print}打印foo行,保存行号,并设置打印后面的行
  4. 如果实际行号大于保存的行号加 3,则将打印设置为关闭
  5. 如果我们需要打印 ( np>0),则打印。
于 2013-07-26T11:44:21.707 回答
1

这可能对你有用(GNU sed);

sed -n '/foo/,+3{p;b};/bar/p' file
于 2013-07-26T12:23:03.730 回答