删除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中删除第一行:
如示例所示,我们的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解决方案慢得多,但学习sed和awk仍然是值得的,因为它们比tail 命令更强大和可扩展。