我有一个包含一些行的文件(难以置信,对:),需要清理它。我想删除除该行的第一个实例之外的所有内容。是否有 Vim 的插件可以让我选择保留该行的第一个实例的行(可视行选择),并删除所有其他行,无论我是否选择了其他行(因为我可能会错过第一个实例在文件的开头)?
如果您知道如何快速选择行,删除文件中除第一个实例之外的所有实例,那也可以。
欢迎所有关于此的想法。
我有一个包含一些行的文件(难以置信,对:),需要清理它。我想删除除该行的第一个实例之外的所有内容。是否有 Vim 的插件可以让我选择保留该行的第一个实例的行(可视行选择),并删除所有其他行,无论我是否选择了其他行(因为我可能会错过第一个实例在文件的开头)?
如果您知道如何快速选择行,删除文件中除第一个实例之外的所有实例,那也可以。
欢迎所有关于此的想法。
我希望你有 awk 可用。如果为真,您可以这样做:
:command! RML exec '%!awk -vl="'.getline(".").'" ''$0==l{if(\!f)print $0;f=1;next;}1'''
这将创建一个名为RML
(Remove Line)的命令
然后将光标移动到要删除重复项的行,键入已删除重复:RML<ENTER>
项,并且只保留第一行。
这种方式将保持原始文件中的行顺序
有关详细信息,您可以查看下面的 gif 截屏视频:
没有 vim 可能更简单:
如果您只想保留 1 次出现的行与正则表达式“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
另一种方法(可能更快!):删除所有行并在正确的位置重新插入第一次出现
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 行出现等)
一个快速的方法是
去你想要的线路
ma
0y$
:g/\V<ctrl-r>"/m'a
:/\V<ctrl-r>"/d