我有一个带有一些行(令人难以置信,对吧:) 的文件,需要清理它。我想删除除该行的第一个实例以外的所有实例。是否有一个Vim插件让我选择保留行的第一个实例的行(视线选择),并删除所有其他的行,无论我是否选择了其中一个(因为我可能会错过第一个实例)在文件的开头)?
如果您想知道如何快速选择该行,请删除文件中除第一个实例之外的所有实例,这样做也会有效。
欢迎所有关于此的想法。
答案 0 :(得分:3)
我希望你有awk可用。如果是,您可以这样做:
:command! RML exec '%!awk -vl="'.getline(".").'" ''$0==l{if(\!f)print $0;f=1;next;}1'''
这将创建一个名为RML
(删除行)的命令
然后将光标移动到要删除重复项的行,键入:RML<ENTER>
删除重复项,只保留第一行。
这种方式将保持原始文件中的行顺序
详细信息,请查看下面的gif截屏视频:
答案 1 :(得分:0)
如果您想要保留的行只发生一次匹配正则表达式“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)