1

私はいくつかの行(信じられないほど、正しい:)を含むファイルを持っており、それをクリーンアップする必要があります。行の最初のインスタンスを除くすべてを削除したいと思います。Vimのプラグインを使用すると、行の最初のインスタンスを保持する行を選択し(視覚的な行選択)、それ以降のインスタンスの1つを選択したかどうかに関係なく、それ以降のすべての行を削除できます(最初のインスタンスを見逃す可能性があるため)ファイルの先頭)?

行をすばやく選択する方法がわかっている場合は、ファイル内の最初のインスタンスを除くすべてを削除します。これも機能します。

これに関するすべてのアイデアを歓迎します。

4

4 に答える 4

0

簡単な方法はこれです

あなたが望むラインに行きます

ma
0y$
:g/\V<ctrl-r>"/m'a
:/\V<ctrl-r>"/d
于 2013-01-11T08:04:52.370 に答える
0

たぶん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つだけあるかどうかのテストなどを追加します)

于 2013-01-09T15:43:50.663 に答える