Difference between revisions of "Comparing files"

From Vifm Wiki
Jump to: navigation, search
(Use "source" tag instead of "syntaxhighlight")
(Comparison script: Make comparison of directories recursive)
Line 1: Line 1:
 
== Comparison script ==
 
== Comparison script ==
  
The script below takes two arguments on the command-line and compares them via <code>[https://en.wikipedia.org/wiki/Diff diff]</code> command. It also echoes generic human-readable answer saying whether two file system objects are equal. As <code>diff</code> compares directories as well as files, paths to directories are valid arguments as well.
+
The script below takes two arguments on the command-line and compares them via <code>[https://en.wikipedia.org/wiki/Diff diff]</code> command. It also echoes generic human-readable answer saying whether two file system objects are equal. As <code>diff</code> is able to compare both directories and files, paths to directories are valid arguments as well.
  
 
<source lang="bash">
 
<source lang="bash">
Line 12: Line 12:
  
 
if [ -f "$1" -a -f "$2" ]; then
 
if [ -f "$1" -a -f "$2" ]; then
     : # OK, do nothing here
+
     args=
 
elif [ -d "$1" -a -d "$2" ]; then
 
elif [ -d "$1" -a -d "$2" ]; then
     : # OK, do nothing here
+
     args='-r'
 
else
 
else
 
     if [ -f "$1" ]; then
 
     if [ -f "$1" ]; then
Line 30: Line 30:
 
fi
 
fi
  
if diff "$1" "$2" > /dev/null 2>&1; then
+
if diff $args "$1" "$2" > /dev/null 2>&1; then
 
     echo 'Equal'
 
     echo 'Equal'
 
else
 
else

Revision as of 17:34, 29 July 2014

Comparison script

The script below takes two arguments on the command-line and compares them via diff command. It also echoes generic human-readable answer saying whether two file system objects are equal. As diff is able to compare both directories and files, paths to directories are valid arguments as well.

#!/bin/bash

if [ $# != 2 ] ; then
    echo 'Expected exactly two arguments'
    exit 1
fi

if [ -f "$1" -a -f "$2" ]; then
    args=
elif [ -d "$1" -a -d "$2" ]; then
    args='-r'
else
    if [ -f "$1" ]; then
        type_of_1='file'
    else
        type_of_1='directory'
    fi
    if [ -f "$2" ]; then
        type_of_2='file'
    else
        type_of_2='directory'
    fi
    echo "Arguments are of different type ($type_of_1/$type_of_2)"
    exit 1
fi

if diff $args "$1" "$2" > /dev/null 2>&1; then
    echo 'Equal'
else
    echo 'Not equal'
fi

Plugging the script into vifm

To use it in Vifm:

  1. Save the script as compare-cmd (not cmp or compare to avoid name conflict with existing tools) at one of directories listed in your $PATH environment variable or under $VIFM/scripts (most likely that it's ~/.vifm/scripts).
  2. On Unix-like operating systems make the script file executable by running
    chmod +x compare-cmp
  3. Add following lines to your vifmrc:
   command! cmpinternal compare-cmd %a %S
   command! cmp : if expand('%c') == expand('%f')
              \ |     echo expand('Comparing %"c and %"C:t ...')
              \ |     cmpinternal %c %C
              \ | else
              \ |     echo expand('Comparing files: %"f ...')
              \ |     cmpinternal %f
              \ | endif

Explanation of key parts:

  • cmpinternal — a trick to invoke external command. Calling execute "!compare-cmd ... %S" reparses command-line which leads to loosing results of command execution (they are overwritten by execution of if-else-endif block).
  • expand('%c') == expand('%f') — check whether only one file is selected in current pane.

Usage

  • Run :cmp without selection or with single file selection to compare files under cursors in two panes.
  • Run :cmp after selecting two files in the current pane to compare them.

Results are printed on the status bar (because of %S macro in cmdinternal).