仅挂到第一行的行,并删除所有其他副本

时间:2013-01-09 13:24:34

标签: vim

我有一个带有一些行(令人难以置信,对吧:) 的文件,需要清理它。我想删除除该行的第一个实例以外的所有实例。是否有一个Vim插件让我选择保留行的第一个实例的行(视线选择),并删除所有其他的行,无论我是否选择了其中一个(因为我可能会错过第一个实例)在文件的开头)?

如果您想知道如何快速选择该行,请删除文件中除第一个实例之外的所有实例,这样做也会有效。

欢迎所有关于此的想法。

4 个答案:

答案 0 :(得分:3)

我希望你有awk可用。如果是,您可以这样做:

  • 在vim中打开您的文件
  • 类型(在一行中):command! RML exec '%!awk -vl="'.getline(".").'" ''$0==l{if(\!f)print $0;f=1;next;}1'''

这将创建一个名为RML(删除行)的命令

  • 然后将光标移动到要删除重复项的行,键入:RML<ENTER>删除重复项,只保留第一行。

  • 这种方式将保持原始文件中的行顺序

  • 无论您的重复行是否继续,这种方式都有效

详细信息,请查看下面的gif截屏视频:

enter image description here

答案 1 :(得分:0)

没有vim可能更简单:

如果您想要保留的行只发生一次匹配正则表达式“aregexp”,

grep "$aregexp" file | head -n 1 > /tmp/thatline #first occurence of the line.
all_other_occurences="$(fgrep -n "$(cat /tmp/thatline)" file | head -n +2 | tac)"
   #fgrep string file : search string in file, literrally, without using regexp
   #head -n +2 (or on some machines: head -n +1) skips the 1st line of the input
   #tac : so that we have line numbers in reverse order (allowing to delete them without moving the next ones up!)
#here add a test to see if all_other_occurence is empty : nothing to do then (there was no lines other than the first one)
#otherwise: 
for linetodelete in "$all_other_occurence" ; do
    # either delete line n in file using sed -i,
    #    or     create&concatenate a vim command that later will be used to
    #           delete those lines from inside vim, via script or copy/paste manually...
done

另一种方法(可能更快!):删除所有行并在第1次出现的地方重新插入

thelinenumber=$( awk '$0~var{print NR;exit}' var="$aregexp" < file)
   #will exit as soon as it finds the 1st occurence
theline="$(sed -e "${thelinenumber}p" < file)" 
fgrep -v "$theline" file > newfile #delete all occurence
awk -v l="$thelinenumber" -v s="$theline" 'NR == l {print s} {print}' file > file.new

我没有检查那些,但我希望你能看到意图并纠正任何语法问题(并添加双重检查,对于空变量,测试是否只有1次出现,等等)

答案 2 :(得分:0)

这是一个快速的方法

转到您想要的行

ma
0y$
:g/\V<ctrl-r>"/m'a
:/\V<ctrl-r>"/d

答案 3 :(得分:0)

我的PatternsOnText plugin提供了

:DeleteDuplicateLinesOf .

命令(以及其他相关命令)就是这样做的。