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

实例介绍

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

  1. $ cat rumenz.txt
  2. 1 rumenz.com
  3. 2 rumenz
  4. 3 入门
  5. 4 小站
  6. 5 入门小站
  7. 6 小站入门
  8. 7 门小
  9. 8 入站
  10. 9 123
  11. 10 rumenxiaozhan

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

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

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

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

使用head命令

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

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

  1. $ head -n -3 rumenz.txt
  2. 1 rumenz.com
  3. 2 rumenz
  4. 3 入门
  5. 4 小站
  6. 5 入门小站
  7. 6 小站入门
  8. 7 门小

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

  1. $ head -n -3 rumenz.txt > tmp.txt && mv tmp.txt output.txt

使用wcsed命令

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

  1. sed 'GIVEN`LINE`NO, $d' input_file

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

  1. $ sed '5,$d' rumenz.txt
  2. 1 rumenz.com
  3. 2 rumenz
  4. 3 入门
  5. 4 小站

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

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

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

  1. $ wc -l rumenz.txt
  2. 10 rumenz.txt

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

  1. $ echo $(($(wc -l <rumenz.txt)-3+1))
  2. 8

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

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

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

  1. $ sed '$(($(wc -l <rumenz.txt)-3+1)),$d' rumenz.txt
  2. sed: -e expression #1, char 2: unknown command: `('

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

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

  1. $ sed "$(($(wc -l <rumenz.txt)-3+1)),$ d" rumenz.txt
  2. 1 rumenz.com
  3. 2 rumenz
  4. 3 入门
  5. 4 小站
  6. 5 入门小站
  7. 6 小站入门
  8. 7 门小

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

  1. $ 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来解决我们的问题

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

  1. $ tac rumenz.txt | sed '1,3 d' | tac
  2. 1 rumenz.com
  3. 2 rumenz
  4. 3 入门
  5. 4 小站
  6. 5 入门小站
  7. 6 小站入门
  8. 7 门小

使用awk命令

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

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

  1. $ awk -v n=3 'NR==FNR{total=NR;next} FNR==total-n+1{exit} 1' rumenz.txt rumenz.txt
  2. 1 rumenz.com
  3. 2 rumenz
  4. 3 入门
  5. 4 小站
  6. 5 入门小站
  7. 6 小站入门
  8. 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的默认操作

返回笔记列表
入门小站