vim / vi / sed:对文件末尾的一定行数进行操作

时间:2013-01-02 01:07:49

标签: linux bash vim sed awk

正如我们可以从vim文件的开头删除(或替换,或者猛拉等)第4到第6行:

:4,6d 

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

:10,12d

但是当他们不知道文件中有多少行时,就不能这样做 - 我将在一批许多文件中使用它。我如何在vim和sed中这样做?

我确实看过this post,但没有发现它有用。

5 个答案:

答案 0 :(得分:10)

好吧,使用vim你可以试试以下内容 - 无论如何都非常直观:

:$-4,$-5d

现在,使用sed我无法找到确切的方法,但如果您可以使用sed之外的其他内容,则可以使用head和{{ 1}}:

tail

答案 1 :(得分:7)

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

:$-2,$substitute/...

在sed中,这并不容易,因为它适用于字符的 stream ,并且不能简单地返回。您必须在保留空间中存储许多最后看到的行,并在流的末尾处理保留空间。 以下是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

答案 2 :(得分:6)

从文件末尾的第4行到第6行:使用tac来反转文件

tac filename | sed 4,6d | tac

答案 3 :(得分: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

答案 4 :(得分: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改为{{1} },循环回到开始,即标签6
  • :a对于行范围P;D7(文件结尾)打印到PS中的第一个换行符,然后删除最多并包含第一个换行符并开始新的周期。

默认情况下,倒数第二个子句会创建窗口,因为行$1会附加到PS中。从第6行到最后,在末尾添加一行,然后打印第一行,然后删除。

可替换地:

7