前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >linux中删除文件的最后N行小总结

linux中删除文件的最后N行小总结

作者头像
入门笔记
发布2022-06-02 16:38:49
7.5K0
发布2022-06-02 16:38:49
举报
文章被收录于专栏:入门小站

实例介绍

首先准备一个rumenz.txt文件:

代码语言:javascript
复制
$ cat rumenz.txt
1  rumenz.com
2  rumenz
3  入门
4  小站
5  入门小站
6  小站入门
7  门小
8  入站
9  123
10 rumenxiaozhan

如上面的输出所示,我们的rumenz.txt包含十行。

现在,假设我们要从rumenz.txt文件中删除最后三行 ( n=3 ) 。

在本教程中,我们将使用四种技术解决问题:

  • 使用 head命令
  • 使用 wcsed 命令
  • 使用 tacsed命令
  • 使用 awk命令

使用head命令

使用head命令,我们可以通过在连字符(-)后面传递一个数字以及-n选项(例如-n -x来打印文件中除最后x行之外的所有行

因此,我们可以使用此选项以直接的方式解决我们的问题:

代码语言:javascript
复制
$ head -n -3 rumenz.txt 
1  rumenz.com
2  rumenz
3  入门
4  小站
5  入门小站
6  小站入门
7  门小

但是 head命令在标准输入中打印结果。我们可以通过临时文件将结果保存回output.txt

代码语言:javascript
复制
$ head -n -3 rumenz.txt > tmp.txt && mv tmp.txt output.txt

使用wcsed命令

使用 sed命令及其地址范围,我们可以快速删除文件中从给定行号开始到最后一行的行:

代码语言:javascript
复制
sed 'GIVEN`LINE`NO, $d' input_file

例如,让我们从第5行删除直到rumenz.txt的结尾:

代码语言:javascript
复制
$ sed '5,$d' rumenz.txt 
1  rumenz.com
2  rumenz
3  入门
4  小站

然而,我们的问题是从输入文件中删除最后三行。由于我们的输入文件有十行,sed命令:sed 8,$d rumenz.txt将是解决问题的方法。

这样,问题就变成了如何计算第一个要删除的行号8

现在,是时候介绍wc命令了。使用带有_-l_选项的 wc命令,我们可以轻松获得文件中的总行数 ( TOTAL ):

代码语言:javascript
复制
$ wc -l rumenz.txt 
10 rumenz.txt

此外,我们可以通过计算TOTAL – n + 1来获得要删除的第一个行号。在我们的例子中,我们有n=3

代码语言:javascript
复制
$ echo $(($(wc -l <rumenz.txt)-3+1))
8

让我们仔细看看上面的命令:

  • wc -l <rumenz.txt:这里我们将 rumenz.txt 文件重定向到 stdin 以跳过输出中的文件名
  • $(wc -l <rumenz.txt):我们使用命令替换来捕获TOTAL结果
  • $((TOTAL – 3+1)):算术扩展将计算数学表达式

现在,让我们将这两个部分组装在一起并尝试解决我们的问题:

代码语言:javascript
复制
$ sed '$(($(wc -l <rumenz.txt)-3+1)),$d' rumenz.txt
sed: -e expression #1, char 2: unknown command: `('

上面的错误原因是因为bash扩展和命令替换不会在单引号之间扩展。

让我们将sed命令中的单引号改为双引号并再次测试:

代码语言:javascript
复制
$ sed "$(($(wc -l <rumenz.txt)-3+1)),$ d" rumenz.txt 
1  rumenz.com
2  rumenz
3  入门
4  小站
5  入门小站
6  小站入门
7  门小

如果我们使用流行的GNU sed,我们可以使用-i选项将更改写回输入文件:

代码语言:javascript
复制
$ sed -i "$(($(wc -l <rumenz.txt)-3+1)),$ d" rumenz.txt

使用tacsed命令

使用sed解决问题的难点 在于计算要删除的第一行号。

但是,如果我们可以颠倒输入文件中的行顺序,问题就会变成从文件中删除前 n 行。一个简单的 sed 单行sed 1,n d可以删除前n行。之后,如果我们再次反转线条,我们的问题就解决了。

tac命令可以反向文件中的行的顺序。也就是说,我们可以尝试通过命令tac INPUT_FILE | sed ‘1,n d’ | tac来解决我们的问题

最后,让我们测试一下它是否适用于我们的示例:

代码语言:javascript
复制
$ tac rumenz.txt | sed '1,3 d' | tac
1  rumenz.com
2  rumenz
3  入门
4  小站
5  入门小站
6  小站入门
7  门小

使用awk命令

AWK命令是一个功能强大的文本处理工具。我们可以让 awk 两次遍历输入文件来解决问题。

在第一遍中,它会找出文件中的总行数,在第二遍中,我们打印我们想要保留的那些行:

代码语言:javascript
复制
$ awk -v n=3 'NR==FNR{total=NR;next} FNR==total-n+1{exit} 1' rumenz.txt rumenz.txt 
1  rumenz.com
2  rumenz
3  入门
4  小站
5  入门小站
6  小站入门
7  门小

最后,让我们了解 one-liner 是如何工作的:

  • -v n=3:声明了一个awk变量 n=3
  • NR==FNR{total=NR;next}:这是第一遍。在这个过程中,awk命令将当前行号保存到一个名为total的变量中。第一遍后,total变量保存了输入文件中的总行数
  • FNR==total-n+1{exit} 1:这是第二遍。如果FNR==total-n+1,则表示我们已经到达需要删除的第一行,因此我们退出。否则,我们只打印该行。在这里非零数字1``true 并触发awk的默认操作
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-11-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 入门小站 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 实例介绍
  • 使用head命令
  • 使用wc和sed命令
  • 使用tac和sed命令
  • 使用awk命令
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档