Comparing files

From Vifm Wiki
Revision as of 14:25, 15 September 2014 by Xaizek (talk | contribs) (Plugging the script into vifm: Fix expansion of file names with quotes)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Comparison script[edit]

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.


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

if [ -f "$1" -a -f "$2" ]; then
elif [ -d "$1" -a -d "$2" ]; then
    if [ -f "$1" ]; then
    if [ -f "$2" ]; then
    echo "Arguments are of different type ($type_of_1/$type_of_2)"
    exit 1

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

Plugging the script into vifm[edit]

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).
  • Double percent sign in arguments for the expand() function (e.g. expand('%%c')) — macros are automatically expanded for user-defined commands, so % symbol should be escaped with itself for expansion to be performed by expand() function. It's important as otherwise unescaped quotes or other special characters in file names can break command syntax.
  • expand('%%c') == expand('%%f') — check whether only one file is selected in current pane.


  • 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).