Contents

删除Linux中文本文件的第一行

1. 概述

当我们使用 Linux 命令行时,我们经常需要处理文本文件。在本教程中,我们将介绍从输入文件中删除第一行的不同方法。

此外,我们将讨论这些方法的性能。

2. 示例介绍

让我们首先创建一个示例文本文件进行处理。我们将使用 CSV 文件作为我们的用例,因为这些文件通常在第一行包含列名。如果我们可以从 CSV 文件中删除第一行,它可以使以后的处理更容易。

因此,让我们为示例创建文件books.csv

$ cat books.csv 
ID, BOOK_TITLE, AUTHOR, PRICE($)
1, A Knock at Midnight, Brittany K. Barnett, 13.99
2, Migrations: A Novel, Charlotte McConaghy, 13.99
3, Winter Counts, David Heska, 27.99
4, The Hour of Fate, Susan Berfield, 30.00
5, The Moon and Sixpence, W. Somerset Maugham, 6.99

在本教程中,我们将使用三种技术从books.csv中删除第一行:

  • 使用sed 命令
  • 使用 awk  命令
  • 使用tail 命令

如示例所示,我们的books.csv仅包含六行。然而,在现实世界中,我们可能会面临更大的文件。

因此,在我们解决解决方案之后,我们将讨论解决方案的性能并找出解决问题的最有效方法。

3. 使用 sed命令

sed是 Linux 命令行中常用的文本处理实用程序。使用sed命令从输入文件中删除第一行 非常简单。

让我们看看如何使用sed解决问题:

$ sed '1d' books.csv
1, A Knock at Midnight, Brittany K. Barnett, 13.99
2, Migrations: A Novel, Charlotte McConaghy, 13.99
3, Winter Counts, David Heska, 27.99
4, The Hour of Fate, Susan Berfield, 30.00
5, The Moon and Sixpence, W. Somerset Maugham, 6.99

上例中的sed命令不难理解。参数‘1d’告诉 sed命令对行号‘1’应用’d’ (删除)操作。**

值得一提的是,如果我们使用 GNU sed,我们可以添加-i(就地)选项将更改写回输入文件,而不是将结果打印到stdout:**

sed -i '1d' books.csv

4. 使用awk 命令

awk是另一个强大的 Linux 命令行文本处理工具。一个简短的awk one-liner 可以解决我们的问题:

$ awk 'NR>1' books.csv
1, A Knock at Midnight, Brittany K. Barnett, 13.99
2, Migrations: A Novel, Charlotte McConaghy, 13.99
3, Winter Counts, David Heska, 27.99
4, The Hour of Fate, Susan Berfield, 30.00
5, The Moon and Sixpence, W. Somerset Maugham, 6.99

如果输入文件的行号 ( NR ) 大于 1 ,则上面的 awk命令打印输入文件中的行。 从 4.1.0 版开始,GNU awk支持inplace 扩展来模拟 GNU sed 的-i(就地)选项**:

gawk -i inplace 'NR>1' books.csv

如果我们的 awk实现没有附带“就地”功能,我们总是可以使用临时文件进行“就地”更改:

awk 'NR>1' books.csv > tmp.csv && mv tmp.csv books.csv

5.使用tail 命令

通常,我们使用“ tail -nx file ”命令从输入文件中获取最后x行。如果我们在“ x ”前面加上“+”号, tail -n +x file”命令将从第x行开始打印,直到文件结束

因此,我们可以将“从文件中删除第一行”问题转换为“获取第二行直到文件末尾”:

$ tail -n +2 books.csv
1, A Knock at Midnight, Brittany K. Barnett, 13.99
2, Migrations: A Novel, Charlotte McConaghy, 13.99
3, Winter Counts, David Heska, 27.99
4, The Hour of Fate, Susan Berfield, 30.00
5, The Moon and Sixpence, W. Somerset Maugham, 6.99

同样,我们可以通过临时文件将更改写回输入文件:

tail -n +2 books.csv > tmp.csv && mv tmp.csv books.csv

6. 性能

我们的 books.csv只有六行,所以我们看到的所有命令几乎都是立即完成的。

然而,在现实世界中,我们通常需要处理更大的文件。让我们讨论我们的方法的性能并找到解决问题的最有效的方法。

首先,我们将创建一个包含 1 亿行的大输入文件:

$ wc -l big.txt 
100000000 big.txt

然后,我们将在我们的大输入文件上测试每个解决方案以删除第一行。

为了对它们的性能进行基准测试,我们将使用 time  命令:

  • sed解决方案:time sed ‘1d’ big.txt > /dev/null
  • awk解决方案:time  awk ‘NR>1’ big.txt > /dev/null
  • tail解决方案: time tail -n +2 big.txt > /dev/null

现在,让我们看看结果: sed 解决方案

real	0m6.630s
user	0m6.053s
sys	0m0.559s

awk 解决方案

real	0m15.799s
user	0m15.282s
sys	0m0.499s

tail 解决方案

real	0m0.582s
user	0m0.097s
sys	0m0.474s

如表所示,  ** tail 命令是解决问题的最有效方法。**它比sed命令快约 13 倍,比awk命令快约 30 倍。

这是因为tail命令一直在 寻找,直到找到目标行号并将内容转储到输出中。因此,它只读取换行符而不进行预处理或保留行的文本

另一方面,  sed 和 awk命令将读取并预处理输入文件的每一行。例如,** awk 命令根据给定的 FS 和 RS 初始化一些内部属性,例如字段、 NF和记录。**因此,即使我们的问题不需要它,它也会增加很多开销。

尽管sed 和 awk 解决方案在解决我们的问题方面比 tail解决方案慢得多,但学习sedawk仍然是值得的,因为它们比tail 命令更强大和可扩展。