从文件中删除额外的标题行,第一行除外

从文件中删除额外的标题行,第一行除外

我有一个看起来像这个玩具示例的文件。我的实际文件有 400 万行,其中大约 10 行我需要删除。

ID  Data1  Data2
1    100    100
2    100    200
3    200    100
ID  Data1  Data2
4    100    100
ID  Data1  Data2
5    200    200

我想删除除了第一行之外看起来像标题的行。

最终文件:

ID  Data1  Data2
1    100    100
2    100    200
3    200    100
4    100    100
5    200    200

我怎样才能做到这一点?

答案1

您可以使用

sed '2,${/ID/d;}'

这将删除 ID 从第 2 行开始的行。

答案2

header=$(head -n 1 input)
(printf "%s\n" "$header";
 grep -vFxe "$header" input
) > output
  1. 将输入文件中的标题行抓取到变量中
  2. 打印标题
  3. 处理文件以grep省略与标题匹配的行
  4. 将上述两个步骤的输出捕获到输出文件中

答案3

对于那些不喜欢大括号的人

sed -e '1n' -e '/^ID/d'
  • n表示pass行号。1
  • d删除所有以以下内容开头的匹配行^ID

答案4

这是一个有趣的。您可以sed直接使用删除第一行的所有副本,并保留其他所有内容(包括第一行本身)。

sed '1{h;n;};G;/^\(.*\)\n\1$/d;s/\n.*$//' input

1{h;n;}sed将第一行放入保留空间,打印它,然后读入下一行 - 跳过第一行的其余命令。 (它也是跳过1第二行的第一个测试,但这并不重要,因为该测试不会应用于第二行。)

G将换行符后跟保留空间的内容附加到模式空间。

/^\(.*\)\n\1$/d如果换行符之后的部分(即从保留空间附加的内容)与换行符之前的部分完全匹配,则删除模式空间的内容(从而跳到下一行)。这是重复标题的行将被删除的地方。

s/\n.*$//删除由命令添加的文本部分G,以便打印的只是文件中的文本行。

然而,由于正则表达式很昂贵,稍微快一点的方法是使用相同的条件(否定)并P打印到换行符,如果换行符后面的部分(即从保留空间附加的内容)完全匹配换行符之前的部分,然后无条件删除模式空间:

sed '1{h;n;};G;/^\(.*\)\n\1$/!P;d' input

给定输入时的输出是:

ID  Data1  Data2
1    100    100
2    100    200
3    200    100
4    100    100
5    200    200

相关内容