How to "destructive vimdiff" ;) two files ?

203 views
Skip to first unread message

meino....@gmx.de

unread,
Oct 6, 2012, 10:50:22 PM10/6/12
to vim...@googlegroups.com
Hi,

There are two files ("A" and "B") - both sorted alphabetically and of comparable
contents.

"A" is missing some entries of "B" and "B" is missing some entries of
"A".

I want to delete all entries both files have in common.

Is this possible with vim in a easy way?

Thank you very much in advance for any help!
Have a nice weekend!
Best regards,
mcc



Gary Johnson

unread,
Oct 7, 2012, 3:04:41 AM10/7/12
to vim...@googlegroups.com
On 2012-10-07, mcc wrote:
> Hi,
>
> There are two files ("A" and "B") - both sorted alphabetically and of comparable
> contents.
>
> "A" is missing some entries of "B" and "B" is missing some entries of
> "A".
>
> I want to delete all entries both files have in common.
>
> Is this possible with vim in a easy way?

There may be a way to do this with Vim, but I would use the comm
command. For example,

comm -23 file1 file2

will produce a list of the lines in file1 that are not in file2.

Regards,
Gary

Christian Brabandt

unread,
Oct 9, 2012, 9:10:13 AM10/9/12
to vim...@googlegroups.com
On Sun, October 7, 2012 04:50, meino....@gmx.de wrote:
> Hi,
>
> There are two files ("A" and "B") - both sorted alphabetically and of
> comparable
> contents.
>
> "A" is missing some entries of "B" and "B" is missing some entries of
> "A".
>
> I want to delete all entries both files have in common.
>
> Is this possible with vim in a easy way?
>
> Thank you very much in advance for any help!

The best way would involve using comm, as Gary suggested. But here is a
way to do it in Vim:

You need to loop over each line and get the diff_hlID() for that position.
Each line, where diff_hlID() returns zero you need to delete.

Of course, you can do it in one step ;)

exe ':g/'. join(map(filter(range(1,line('$')), '!diff_hlID(v:val, 0)'), '
''\%''.v:val."l"'), '\|'). '/d'

But, this works only once, you can't do this for all buffers at the
same time, since after you changed the first buffer the syntax highlighting
for the other will be completely different and there will be no more
items being in common at the following buffers.


regards,
Christian

Ben Fritz

unread,
Oct 9, 2012, 11:53:07 AM10/9/12
to vim...@googlegroups.com, cbl...@256bit.org
On Tuesday, October 9, 2012 8:10:29 AM UTC-5, Christian Brabandt wrote:
>
> You need to loop over each line and get the diff_hlID() for that position.
>
> Each line, where diff_hlID() returns zero you need to delete.
>
>
>
> Of course, you can do it in one step ;)
>
>
>
> exe ':g/'. join(map(filter(range(1,line('$')), '!diff_hlID(v:val, 0)'), '
>
> ''\%''.v:val."l"'), '\|'). '/d'
>
>
>
> But, this works only once, you can't do this for all buffers at the
>
> same time, since after you changed the first buffer the syntax highlighting
>
> for the other will be completely different and there will be no more
>
> items being in common at the following buffers.
>

But, you could next undo the (single) change in the first buffer, repeat the process on the second buffer, then redo the change in the first buffer.

Christian Brabandt

unread,
Oct 9, 2012, 12:42:14 PM10/9/12
to vim...@googlegroups.com
Hi Ben!
Even better, store the result for each window and execute it afterwards:

:let delete={}
:windo if &diff |:let delete[bufnr('')]=
join(map(filter(range(1,line('$')), '!diff_hlID(v:val, 0)'),
'''\%''.v:val."l"'), '\|')|endif
:windo if &diff | exe ":g/". delete[bufnr('')]."/d"|endif
:unlet delete

(each line starting with ':' is a single line, no linewraps)


regards,
Christian
--
Unter Rationalisierung verstehen die meisten Postminister, da� man
die Geb�hren laufend erh�ht und die Zustellung st�ndig verschlechtert.
-- Cyril Northcote Parkinson
Reply all
Reply to author
Forward
0 new messages