我有一个包含以下寄存器的 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