11

就像我们可以在 vim 中删除(或替换,或 yank 等)文件开头的第 4 到第 6 行一样:

:4,6d 

我想从文件末尾删除(或替换,或猛拉等)第 4 行到第 6 行。这意味着,如果文件有 15 行,我会这样做:

:10,12d

但是当他们不知道文件中有多少行时,就无法做到这一点——我将在一批许多文件上使用它。我如何在 vim 和 sed 中执行此操作?

我确实看过这篇文章,但没有发现它有用。

4

5 回答 5

10

好吧,使用vim您可以尝试以下操作 - 无论如何,这非常直观:

:$-4,$-5d

现在,使用sed我找不到确切的方法来做到这一点,但如果你可以使用 以外的东西sed,这里有一个解决方案headtail

head -n -4 file.txt && tail -2 file.txt
于 2013-01-02T01:20:41.890 回答
7

在 Vim 中,您可以从$代表最后一行的 中减去行号,例如,这将适用于最后 3 行:

:$-2,$substitute/...

在 sed 中,这并不容易,因为它适用于字符,不能简单地返回。您必须在保持空间中存储一些最后看到的行,并在流的末尾处理保持空间。以下是sed1line.txt中的一些食谱:

# print the last 10 lines of a file (emulates "tail")
sed -e :a -e '$q;N;11,$D;ba'

# print the last 2 lines of a file (emulates "tail -2")
sed '$!N;$!D'

# delete the last 2 lines of a file
sed 'N;$!P;$!D;$d'

# delete the last 10 lines of a file
sed -e :a -e '$d;N;2,10ba' -e 'P;D'   # method 1
sed -n -e :a -e '1,10!{P;N;D;};N;ba'  # method 2
于 2013-01-02T01:23:05.143 回答
6

从文件末尾倒数第 4 行到第 6 行:用于tac反转文件

tac filename | sed 4,6d | tac
于 2013-01-02T02:43:57.290 回答
2

您可以在 awk 中使用 2 次通过,第一次通过计算行数,第二次通过打印或删除您喜欢的任何行,例如

awk 'NR==FNR{numLines++;next} {fromEnd = numLines - FNR} fromEnd > 6 || fromEnd < 4' file file

awk 'NR==FNR{numLines++;next} {fromEnd = numLines - FNR} fromEnd < 6 && fromEnd > 4' file file
于 2013-01-02T21:10:39.080 回答
1

这可能对您有用(GNU sed):

sed -r ':a;${s/([^\n]*\n){3}//;q};N;7,$!ba;P;D' file

这是通过在模式空间 (PS) 中创建一个 6 行的移动窗口,然后在遇到最后一行时删除其中的前三行来实现的。

  • :a是一个循环标签
  • ${s/([^\n]*\n){3}//;q}删除文件末尾 PS 的前三行并退出。
  • N添加一个换行符,然后将下一行添加到 PS。
  • 7,$!ba' 如果不是7$(文件结尾)的行,即行到1,则6循环回到开头,即标签:a
  • P;D7对于要(文件结尾)的行范围,$打印到 PS 中的第一个换行符,然后删除直到并包括第一个换行符并开始一个新的循环。

倒数第二个子句默认创建窗口,因为16附加到 PS 中的行。从行7到末尾,在末尾添加一行,打印第一行然后删除。

或者:

sed -e ':a' -e '$s/\([^\n]*\n\)\{3\}//' -e '$q' -e 'N' -e '7,$!ba' -e 'P' -e 'D' file
于 2013-01-02T13:20:15.467 回答