在 Linux 上的 Bash 中从某一行开始解析文件

在 Linux 上的 Bash 中从某一行开始解析文件

我有一个包含以下寄存器的 CSV 文件:

Name,Phone,Country
John,N/A,USA
Max,N/A,USA

Name,Color,Size
John,Blue,M
Max,Red,S

如何使用 bash 仅读取 Name、Color、Size 及以后的寄存器?

此外,如何限制输出直到达到 EOF 或空白行?因此:

Name,Phone,Country
John,N/A,USA
Max,N/A,USA

Name,Color,Size
John,Blue,M
Max,Red,S

Dummy,Dummy,Dummy
Foo,Foo,Bar

不会输出这个:

John,Blue,M
Max,Red,S

Dummy,Dummy,Dummy
Foo,Foo,Bar

但只有这个:

John,Blue,M
Max,Red,S

我已经尝试过 grep 和 sed,但是没有成功,我也尝试过 tail,但是在读取文件之前行数是未知的。

答案1

使用 awk

$ awk '/^$/{f=0} f{print} /Name,Color,Size/{f=1}' file
John,Blue,M
Max,Red,S

怎么运行的

awk 脚本有一个变量,f它作为一个标志来识别我们何时位于一个Name,Color,Size块内。

  • /^$/{f=0}

    在空白行上设置f=0以表示我们已经超出了Name,Color,Size限制。

  • f{print}

    当我们处于块中时f==1,打印该行。

  • /Name,Color,Size/{f=1}

    当我们到达Name,Color,Size标题时,设置f=1为信号,表示我们处于块中。

使用 GNU sed

$ sed -n '/Name,Color,Size/{:a; n; /./{p; ba;}}' file
John,Blue,M
Max,Red,S

怎么运行的

  • -n

    告诉 sed 不要打印任何内容,除非我们明确要求。

  • /Name,Color,Size/{...}

    如果该行包含Name,Color,Size标题,则执行括号内的命令:

    • :a;

      这定义了一个标签a

    • n;

      下一行内容如下。

    • /./{p; ba;}

      如果下一行不是空白,则打印它(p)并分支(b)回标签a

    这样,块内的所有行都将被读取和打印,并且打印会在第一个空行处停止。

答案2

您可以使用 sed 来仅显示某一行之后的内容,例如

sed -e '0,/Name,Color,Size/d' <file>

所以你只会看到后面几行Name,Color,Size

相关内容