4

I can drag two files into the Meld GUI. I can also click File comparison (see Screenshot), then choose one file, compare that to nothing, then choose the second file. This seems roundabout. I want to compare two files, preferably in a multiselect filepicker GUI.

Even better would be to right-click one or two files in Nautilus to run Meld.

Is either of those possible?

3 Answers 3

6

Personally, I always run meld from the terminal, so I give the two file names there:

meld fileA fileB

Using the GUI, all you need to do is select two files. I don't see why you need to "compare it to nothing". You just select the first file and then the second:

enter image description here

3
  • You're right! I never noticed that after choosing one file for File Comparison, the GUI element under Directory Comparison is actually not for Directory Comparison anymore but rather for a second file!
    – Joshua Fox
    May 25, 2015 at 18:45
  • Also, I found this about comparing two files straight out of Nautilus askubuntu.com/questions/112164/…
    – Joshua Fox
    May 25, 2015 at 18:45
  • Any idea how one can integrate Meld with Nautilus in 22.10? Feb 10, 2023 at 5:53
0

If you want to compare two files with meld from Nautilus, you can write some scripts that can be activated through the right-click menu on a file or folder. The scripting language for Nautilus scripts may be bash, python, perl or ruby, just to list some examples. In this answer I'll show a solution based on bash.

The first thing to is to create the scripts folder with the terminal command:

mkdir -p ~/.local/share/nautilus/scripts

All scripts will go into this folder. Once a script is in the folder, it will not show up in the right-click context menu until you make it executable with the terminal command:

chmod +x <script_name>

Once you have at least one executable script, then it will appear under 'scripts' in the context menu, as shown below (the image is just a reference taken from a StackExchange post, currently I don't have acces to my own Ubuntu for a more "personal" screenshot).

Example of a nautilus script from right-context menu

Now, you can add to that folder the following two files, that I have named Meld (select first item) and Meld (select second item). I have not put the .sh just for an aestethic reason (the extension appears in the context menu, and I don't like it): the presence of the shebang line at the beginning of every file it's enough for the system to understand how to execute them.

Content of Meld (select first item) file:

#!/bin/bash
#-------------------------------------------------------------------------------
# Script:  Meld (select first item)
# Author:  Lorenz Keel (AskUbuntu)
# Purpose: Define left-side compare operand for meld
# Note:    Don't forget to run: chmod +x <script_name>
#------------------------------------------------------------------------------

# Exit values
STATUS_OK=0
STATUS_ERROR=1

# Check meld package installation
if [ -n "$(command -v meld)" ]; then
  # Create temp file
  TMP_FILE="/tmp/nautilus-compare.txt"
  # Check if the Nautilus environment variable is empty
  if [ -z "${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS}" ]; then
    # If it's blank, exit with notification of error
    exit "${STATUS_ERROR}"
  else
    # Remove the previous version of the temporary file
    if [ -f "${TMP_FILE}" ]; then
      rm -rf "${TMP_FILE}"
    fi
    # Put quotes around every full path
    while read -r FULL_PATH; do
      echo "'${FULL_PATH}'" | tee "${TMP_FILE}"
    done < <(echo "${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS::-1}")
  fi
else
  # Get the name of the current icon theme
  ICON_THEME="$(gsettings get org.gnome.desktop.interface icon-theme | tr -d "'")"
  # Set the value of the notification icon
  if [ -f "/usr/share/icons/${ICON_THEME}/scalable/status/dialog-error-symbolic.svg" ]; then
    NOTIFY_ICON="/usr/share/icons/${ICON_THEME}/scalable/status/dialog-error-symbolic.svg"
  else
    NOTIFY_ICON="error"
  fi
  # Specifies the timeout in seconds after which the dialog is closed
  NOTIFY_TIMEOUT=5000
  TEXT_ERROR="Installare meld per usare questo script"
  notify-send -t "${NOTIFY_TIMEOUT}" -i "${NOTIFY_ICON}" "${TEXT_ERROR}"
fi

# Exit with notification of success
exit "${STATUS_OK}"

The above files does not trigger yet meld, but simply creates a temporary files that contains the list of the files that are selected in Nautilus when you press the Meld (select first item) item in the context menu. The selected files are read from the special variable NAUTILUS_SCRIPT_SELECTED_FILE_PATHS that serves for this specific purpose. The remaining part of the script triggers a notification with the proper icon in the Ubuntu top bar in case of errros.

Content of Meld (select first item) file:

#!/bin/bash
#-------------------------------------------------------------------------------
# Script:  Meld (select second item)
# Author:  Lorenz Keel (AskUbuntu)
# Purpose: Define right-side compare operand for meld
# Note:    Don't forget to run: chmod +x <script_name>
#------------------------------------------------------------------------------

# Exit values
STATUS_OK=0
STATUS_ERROR=1

# Check meld package installation
if [ -n "$(command -v meld)" ]; then
  # Temp file location
  TMP_FILE="/tmp/nautilus-compare.txt"
  # Check if the Nautilus environment variable is empty
  if [ -z "${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS}" ]; then
    # If it's blank, exit with notification of error
    exit "${STATUS_ERROR}"
  else
    if [ -f "${TMP_FILE}" ]; then
      # Put quotes around every full path
      while read -r FULL_PATH; do
        echo "'${FULL_PATH}'" | tee -a "${TMP_FILE}"
      done < <(echo "${NAUTILUS_SCRIPT_SELECTED_FILE_PATHS::-1}")
    else
      # Temp file is absent, left item has not been selected
      exit "${STATUS_ERROR}"
    fi
  fi
  # Open meld
  tail -2 "${TMP_FILE}" | xargs meld &
  # Wait before deleting the temp file
  sleep 1s && rm -rf "${TMP_FILE}"
else
  # Get the name of the current icon theme
  ICON_THEME="$(gsettings get org.gnome.desktop.interface icon-theme | tr -d "'")"
  # Set the value of the notification icon
  if [ -f "/usr/share/icons/${ICON_THEME}/scalable/status/dialog-error-symbolic.svg" ]; then
    NOTIFY_ICON="/usr/share/icons/${ICON_THEME}/scalable/status/dialog-error-symbolic.svg"
  else
    NOTIFY_ICON="error"
  fi
  # Specifies the timeout in seconds after which the dialog is closed
  NOTIFY_TIMEOUT=5000
  TEXT_ERROR="Installare meld per usare questo script"
  notify-send -t "${NOTIFY_TIMEOUT}" -i "${NOTIFY_ICON}" "${TEXT_ERROR}"
fi

# Exit with notification of success
exit "${STATUS_OK}"

This second script fills the temporary files with the second item of the comparison and then run meld.

You can create these files with you preferred text editor, such as nano (from terminal) or gedit and gnome-text-editor (if you prefer a GUI). The important thing is to save them in the folder I mentioned at the beginning of this answer and enable execution rights on them.

These scripts have been written by myself for my personal usage, my minimal debugging showed me that they work for the simple tasks I ask them to do, I'm aware that probably they can be improved a lot.

0

Here is a dash script for the automation of comparing [ folders/files / office/pdf documents / archives ] (the script uses diff / Meld by default - for the comparison; it also compares the contained URLs (...:\\...) in case of a .html/.htm/.pdf file):

#!/bin/dash
## Supported shells: dash, bash, zsh, ksh

PrintDesktopFile () {
    cat<<EOF
[Desktop Entry]
Name=File Comparer
Comment=Compares [ folders/files / office/pdf documents / archives ] using 1. diff -r / 2. diff -r -q / 3. Meld
TryExec=$terminal_emulator
Exec=$terminal_emulator_plus_launch_flag "$current_shell_full_path" "$current_script_path" OPEN_WITH_MENU %U
Terminal=$1
Type=Application
Icon=utilities-terminal
Categories=Utility;
MimeType=inode/directory;text/plain;application/x-tar;application/x-gtar;application/x-compressed-tar;application/x-bzip-compressed-tar;application/x-tar-bz2;application/x-bzip2;application/zip;application/vnd.openxmlformats-officedocument.wordprocessingml.document;application/vnd.openxmlformats-officedocument.presentationml.presentation;application/vnd.openxmlformats-officedocument.presentationml.slideshow;application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;application/vnd.oasis.opendocument.text;application/vnd.oasis.opendocument.spreadsheet;application/vnd.oasis.opendocument.presentation;application/pdf
EOF
}

PrintMenu () {
    {
    printf '\n%s\n' "Choose one option: "
    printf '%s\n' "Press: "
    printf '%s\n' "    1 - Compare with diff -r the previously selected files/folders"
    printf '%s\n' "    2 - Compare with diff -r -q the previously selected files/folders"
    printf '%s\n' "    3 - Compare with Meld the previously selected files/folders"
    printf '%s\n' "    0 - EXIT script"
    printf '%s\n' "    - - FORCE EXIT (EXIT terminal)"
    }>"$print_to_screen"
}

GetTerminalEmulatorPlusLaunchFlagLinux () {
    
    terminal_emulator_raw="$(ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$$")))")))")"
    if [ ! "${terminal_emulator_raw#*"tmux"*}" = "$terminal_emulator_raw" ]; then
        terminal_emulator_raw="$(ps -o comm= -p "$(($(ps -o ppid= -p "$(($(ps -o sid= -p "$(tmux display-message -p "#{client_pid}")")))")))")"
    fi
    terminal_emulator="${terminal_emulator_raw%"-"}"
    
    if [ "$terminal_emulator" = "gnome-console" ] || [ "$terminal_emulator" = "gnome-terminal" ]; then
        terminal_emulator_plus_launch_flag="\"$terminal_emulator\" --"
    elif [ "$terminal_emulator" = "lxterminal" ] || [ "$terminal_emulator" = "qterminal" ]; then
        #For LXDE and LXQt for example: the shell can be called directly (no terminal emulator needed):
        terminal_emulator_plus_launch_flag=""
    else
        terminal_emulator_plus_launch_flag="\"$terminal_emulator\" -e"
    fi
}

get_char () {
    {
        saved_tty_settings=$(stty -g); #save initial tty settings
        stty raw -echo #enable special characters (erase, kill, werase, rprnt) and disable echo-ing
        dd count=1 2>/dev/null #read (copy) and print: 1 input block
        stty "$saved_tty_settings" #restore initial tty settings
    }</dev/tty 2>/dev/null||{ printf '\n%s\n\n' "ERROR: Could not read character!">&2; }
}

PrintJustInTitle () {
    printf "\033]0;$1\007">"$print_to_screen"
}

CheckFilesFoldersToCompare () {
    if [ -z "$files_folders_to_compare" ]; then
        printf '%s\n' "Please add files/folders to the comparison queue first!"
        exit_code=1
    else
        error="false"
        IFS='
'
        for file in $(cat "$stored_file_paths_file_path"); do
            if [ ! -e "$file" ] || [ ! -r "$file" ]; then
                printf '%s\n' "ERROR: input file/folder: \"$file\" does not exist or is not readable!"
                error="true"
            fi
        done
        unset IFS
        if [ "$error" = "true" ]; then
            printf '\n%s\n\n' "Please: Try to readd files and compare them afterwards..."
            exit_code=1
        fi
    fi
}

GetOSType () {
    if [ -n "$1" ]; then
        case "$(uname -s)" in
        *"Linux"* )
            eval $1="Linux"
            ;;
        *"Darwin"* | *"BSD"* )
            eval $1="BSD-based"
            ;;
        * )
            eval $1="Other"
            ;;
        esac
    else
        printf '%s\n' 'ERROR: GetOSType: Expected 1 parameter!'>&2
        {
        printf '%s\n' 'Press Enter to exit...';
        CleanUp; read temp;
        }>"$print_to_screen"
    fi
}

GetCurrentShell () {
    if [ -n "$BASH_VERSION" ]; then current_shell_name="bash";
    elif [ -n "$ZSH_VERSION" ]; then current_shell_name="zsh";
    elif [ -n "$KSH_VERSION" ]; then current_shell_name="ksh";
    elif [ "$PS1" = '$ ' ]; then current_shell_name="dash";
    else current_shell_name="dash"; #default shell
    fi
    current_shell_full_path="$(which "$current_shell_name")"
    
    eval $1=\"\$current_shell_name\"
    eval $2=\"\$current_shell_full_path\"
}

PrintSavedBreakTimeoutFromFile() {
    cat "$temp_break_timeout_state_file" 2>/dev/null
}

PrepareExitAndExit () {
    if [ "$input_answer" = "1" ] || [ "$input_answer" = "2" ]; then
        if [ "$OPEN_WITH_MENU" = "OPEN_WITH_MENU" ]; then
            {
            printf '%s\n' "Press Enter to exit...";
            CleanUp; read temp;
            }>"$print_to_screen"
        fi
    else
        if [ ! "$1" = "RUN" ]; then
            PrintJustInTitle ""
            if [ -n "$TEMPORARY_EXTRACT_PATH" ] && [ -n "$TEMPORARY_EXTRACT_FOLDER" ]; then
                rm -R -f "$output_dir/"*
            fi
        fi>"$print_to_screen"
    fi
    
    exit $exit_code
}

ExtractFirstAndLastPathComponent () {
    eval current_path="\"\$$1\""
    
    first_path_component=""
    last_path_component=""
    
    if [ -n "$current_path" ]; then
        #Remove trailing '/' characters:
        while [ ! "${current_path%"/"}" = "$current_path" ]; do
            current_path="${current_path%"/"}"
        done
        
        if [ -z "$current_path" ]; then
            eval current_path=\"\$$1\"
        fi
        
        last_path_component="${current_path##*"/"}"
        first_path_component="${current_path%"$last_path_component"}"
    fi
    
    eval $2="\"\$first_path_component\""
    eval $3="\"\$last_path_component\""
}

ExtractFileIfArchive () {
    eval fileEFIA=\"\$$1\"
    
    if [ -z "$first_time" ]; then cat '/dev/null'>"$stored_file_paths_file_path"; first_time="defined"; fi
    
    case "$fileEFIA" in
        *'.zip' | *'.odt' | *'.ods' | *'.odp' | *'.docx' | *.'xlsx' | *'.pptx' | *'.ppsx' | *'.pdf' | *'.htm' | *'.html' | *'.tar.'* | *'.bz2' | *'.xz' | *'.gz' | *'.tgz' | *'.tar' | '/dev/null' )
            error="false"
            case "$fileEFIA" in
                *'.pdf' )
                    CheckUtilities pdftotext pdftohtml
                ;;
            esac
            if [ "$error" = "false" ]; then
                ExtractArchive fileEFIA fileEFIA_extracted
                output1="$(printf '%s' "$fileEFIA_extracted"|sed "s/'/$Q\"\$Q\"$Q/g")"
                printf "'%s' " "$output1"
            fi
        ;;
        * )
            output1="$(printf '%s' "$fileEFIA"|sed "s/'/$Q\"\$Q\"$Q/g")"
            printf "'%s' " "$output1"
            fileEFIA_extracted="$fileEFIA"
        ;;
    esac
    
    printf '%s\n' "$fileEFIA_extracted">>"$stored_file_paths_file_path"
}

ExtractArchive () {
    eval current_archive_path="\"\$$1\""
    
    if [ "$current_archive_path" = '/dev/null' ]; then
        {
        cd "$output_dir" || error="true"
        mkdir "null"; cd "null" || error="true"
        full_current_archive_extract_to_path="$output_dir/null"
        cat /dev/null>"$full_current_archive_extract_to_path""/""temp.links.txt" || error="true"
        } 2>/dev/null
        if [ "$error" = "true" ]; then printf '%s\n' "ERROR: Could not create/access <output> directory structure!">&2; { printf '%s\n' "Press Enter to exit..."; CleanUp; read temp; kill $$; }>"$print_to_screen"; fi

    else
        full_current_archive_path="$current_archive_path"
        
        ExtractFirstAndLastPathComponent current_archive_path fpc_current_archive_path lpc_current_archive_path
        cd "$fpc_current_archive_path"
        fpc_current_archive_path="$PWD"
        
        ExtractFirstAndLastPathComponent fpc_current_archive_path fpc_fpc_current_archive_path lpc_fpc_current_archive_path
        current_archive_name_ext="${lpc_current_archive_path}"
        if [ ! -d "$current_archive_path" ]; then
            current_archive_name_ext_plus="$current_archive_name_ext""_extract"
        else
            current_archive_name_ext_plus="$current_archive_name_ext"
        fi
        full_current_archive_extract_to_path="$output_dir/$lpc_fpc_current_archive_path/$current_archive_name_ext_plus"

        
        if [ ! -e "$full_current_archive_extract_to_path" ]; then
            {
            error="false"
            cd "$output_dir" || error="true"
            mkdir "$lpc_fpc_current_archive_path"; cd "$lpc_fpc_current_archive_path" || error="true"
            mkdir "$current_archive_name_ext_plus"; cd "$current_archive_name_ext_plus" || error="true"
            } 2>/dev/null
            if [ "$error" = "true" ]; then printf '%s\n' "ERROR: Could not create/access <output> directory structure!">&2; { printf '%s\n' "Press Enter to exit..."; CleanUp; read temp; kill $$; }>"$print_to_screen"; fi
            
            case "$current_archive_path" in
                *'.zip' | *'.odt' | *'.ods' | *'.odp' | *'.docx' | *.'xlsx' | *'.pptx' | *'.ppsx' )
                    unzip "$full_current_archive_path" -d "$full_current_archive_extract_to_path"
                ;;
                *'.pdf' )
                    pdftotext "$full_current_archive_path" "$full_current_archive_extract_to_path""/""temp.text.txt"
                    pdftohtml "$full_current_archive_path" "$full_current_archive_extract_to_path""/""temp.html"
                    cat "$full_current_archive_extract_to_path""/"*|eval "$extract_urls_command">>"$full_current_archive_extract_to_path""/""temp.links.txt"
                    full_current_archive_extract_to_path="$full_current_archive_extract_to_path"
                ;;
                *'.htm' | *'.html' )
                    cp "$full_current_archive_path" "$full_current_archive_extract_to_path""/""temp.html"
                    cat "$full_current_archive_extract_to_path""/"*|eval "$extract_urls_command">>"$full_current_archive_extract_to_path""/""temp.links.txt"
                    full_current_archive_extract_to_path="$full_current_archive_extract_to_path"
                ;;
                *'.bz2' | *'.xz' | *'.gz' )
                    cp "$full_current_archive_path" "$full_current_archive_extract_to_path"
                    case "$current_archive_path" in
                        *'.bz2' ) bzip2 "$full_current_archive_extract_to_path/""$current_archive_name_ext" -d "$full_current_archive_extract_to_path"; ;;
                        *'.xz' ) xz "$full_current_archive_extract_to_path/""$current_archive_name_ext" -d "$full_current_archive_extract_to_path"; ;;
                        *'.gz' ) gzip -d "$full_current_archive_extract_to_path/""$current_archive_name_ext"; ;;
                    esac
                    case "${current_archive_name_ext%"."*}" in
                        *'.tar' )
                            tar -xvf "$full_current_archive_extract_to_path/${current_archive_name_ext%"."*}" -C "$full_current_archive_extract_to_path"
                            rm "$full_current_archive_extract_to_path/${current_archive_name_ext%"."*}"
                        ;;
                    esac
                ;;
                *'.tgz' | *'.tar' )
                    tar -xvf "$full_current_archive_path" -C "$full_current_archive_extract_to_path"
                ;;
            esac >/dev/null 2>/dev/null
        else
            cd "$full_current_archive_extract_to_path"
        fi
    fi
    eval $2=\"\$full_current_archive_extract_to_path\"
}

CheckUtilities () {
    #Check if any of the necessary utilities is missing:
    error="false"
    
    for utility; do
        which $utility>/dev/null 2>/dev/null || { printf "\n%s\n" "ERROR: the '$utility' utility is not installed!">&2; error="true"; }
    done
    
    if [ "$error" = "true" ]; then
        {
        printf "\n%s\n" "Press Enter to exit...">&2
        CleanUp; read temp;
        kill -s PIPE -- -$$; #kill all children processes, suppressing "Terminated" message
        }>"$print_to_screen"
    fi
}

CleanUp () {
    IFS="$initial_IFS"
    cd "$initial_dir"
}


set +f #Enable globbing (POSIX compliant)
setopt no_nomatch 2>/dev/null #Enable globbing (zsh)

Q="'"

initial_IFS="$IFS"

cd "${0%/*}" 2>/dev/null
current_script_path="$(pwd -P)/${0##*/}"

GetCurrentShell current_shell_name current_shell_full_path

APPS_DESKTOP_FILES_FOLDER="$HOME/.local/share/applications" #(for Linux) this is the default location for .desktop files (should not be changed)

desktop_file_name_ext="FileComparerScript.desktop" #(for Linux) can be changed
desktop_file_path="$APPS_DESKTOP_FILES_FOLDER""/""$desktop_file_name_ext" #(for Linux)
stored_file_paths_file_parent_dir_path="$APPS_DESKTOP_FILES_FOLDER" #can be changed

if [ ! -e "$stored_file_paths_file_parent_dir_path" ]; then
    stored_file_paths_file_parent_dir_path="$HOME" #can be changed
fi

stored_file_paths_file_path="$stored_file_paths_file_parent_dir_path""/"'FileComparerScriptSettings.txt'
temp_break_timeout_state_file="$stored_file_paths_file_parent_dir_path""/"'temp_break_timeout_state_file.txt'
temp_compared_status_file="$stored_file_paths_file_parent_dir_path""/"'temp_compared_status_file.txt'
temp_to_be_resetted_status_file="$stored_file_paths_file_parent_dir_path""/""temp_to_be_resetted.txt"

NL2=$(printf '%s' "\n\n") #Store New Line for use with sed
insert_NL_before_URLs_command='sed -E '"'"'s/([a-zA-Z]*\:\/\/)/'"\\${NL2}"'\1/g'"'"
strip_NON_URL_text_command='sed -E '"'"'s/((.*([^a-zA-Z+])|([a-zA-Z])))(([a-zA-Z])*\:\/\/)([^ ^'"${TAB}"'^>^<]*).*/\4\5\7/g'"'"
delete_lines_not_containing_an_URL='sed -E '"'"'/.*\:\/\/.*/!d'"'"
extract_urls_command="$insert_NL_before_URLs_command|$strip_NON_URL_text_command|$delete_lines_not_containing_an_URL"

print_to_screen='/dev/tty'

CR=$(printf '\r')

default_menu_option="1" #can be changed [ 1..3 ]

GetOSType OS_TYPE

exit_code=0

OPEN_WITH_MENU=""; if [ "$1" = "OPEN_WITH_MENU" ]; then OPEN_WITH_MENU="OPEN_WITH_MENU"; shift; fi
if [ "$1" = "--install" ]; then
    
    IFS='
'
    
    if [ "$OS_TYPE" = "Linux" ]; then
        {
            CheckUtilities grep update-desktop-database cat ps
            
            cat '/dev/null'>"$desktop_file_path"
            
            GetTerminalEmulatorPlusLaunchFlagLinux
            
            #terminal_visible=false/true <=> not show / show: the initial launcher app (terminal) window
            #for LXDE and LXQt Desktop Environments: use "true"; otherwise: use "false"
            if [ -z "$terminal_emulator_plus_launch_flag" ]; then
                terminal_visible="true"
            else
                terminal_visible="false"
            fi
            
            PrintDesktopFile $terminal_visible>"$desktop_file_path"
            
            favorite_icons_list=$(dconf read /org/gnome/shell/favorite-apps 2>/dev/null)
            printf '%s' "$favorite_icons_list"|grep -F "$desktop_file_name_ext">/dev/null||{
                dconf write /org/gnome/shell/favorite-apps "${favorite_icons_list%"]"}"", ""'$desktop_file_name_ext'""]"
            } 2>/dev/null
            # Update database of desktop entries cache:
            update-desktop-database "$APPS_DESKTOP_FILES_FOLDER"
        } && {
            printf '\n%s\n\n' "Installed in the Desktop Favorite Apps Ribbon."
        } || {
            printf '\n%s\n\n' "ERROR: Install encountered errors."
        }
    else
        printf '\n%s\n\n' "ERROR: Currently, install is implemented only for the Linux operating systems!"
    fi
fi
if [ -z "$1" ]; then
    printf '%s\n' "true">"$temp_to_be_resetted_status_file"
fi
if [ ! "$1" = "--install" ]; then
    
    CheckUtilities mkdir cat diff kill stty dd unzip tar cp
    
    {
        [ "$OS_TYPE" = "Linux" ] && [ -e '/dev/shm' ] && {
            TEMPORARY_EXTRACT_PATH='/dev/shm'
        } 2>/dev/null || {
            [ "$OS_TYPE" = "BSD-based" ] && [ -e "$HOME" ] && {
                TEMPORARY_EXTRACT_PATH="$HOME"
            }
        } || {
            printf "Please provide TEMPORARY_EXTRACT_PATH: ">&2; read TEMPORARY_EXTRACT_PATH>"$print_to_screen";
        }
        TEMPORARY_EXTRACT_FOLDER='TEMP_EXTR_FOLDER'
    }>/dev/null
    
    initial_dir="$PWD"
    
    output_dir=""
    error="false"
    {
        [ -n "$TEMPORARY_EXTRACT_PATH" ] && cd "$TEMPORARY_EXTRACT_PATH" && {
            if [ ! -e "$TEMPORARY_EXTRACT_FOLDER" ]; then
                mkdir "$TEMPORARY_EXTRACT_FOLDER" || error="true"
            fi
            cd "$TEMPORARY_EXTRACT_FOLDER" && output_dir="$PWD" || {
                error="true"
            }
        } || error="true"
    } 2>/dev/null
    if [ "$error" = "true" ]; then
        printf '%s\n' "Error: Could not access temporary folder \"$TEMPORARY_EXTRACT_FOLDER\" in the extract location: \"$TEMPORARY_EXTRACT_PATH\"!">&2
        { printf '%s\n' "Press Enter to exit..."; CleanUp; read temp; }>"$print_to_screen"; exit 1
    fi
    
    cd "$initial_dir"
    
    
    if [ ! -e "$stored_file_paths_file_path" ]; then
        cat '/dev/null'>"$stored_file_paths_file_path"
    fi
    
    PrintJustInTitle "File Comparer"
    
    if [ -e "$1" ]; then
        #######
        if [ -z "$(cat "$temp_compared_status_file" 2>/dev/null)" ]; then
            printf '%s\n' "compared">"$temp_compared_status_file" 2>/dev/null
        else
            cat '/dev/null'>"$temp_compared_status_file" 2>/dev/null
        fi
        
        if [ "$(cat "$temp_to_be_resetted_status_file")" = "true" ]; then
            cat '/dev/null'>"$stored_file_paths_file_path"
            printf '%s\n' "false">"$temp_to_be_resetted_status_file"
        fi
        #######
        
        for file; do
            files_folders_to_compare=$( \
                IFS='
'; \
                for current_file in $(cat "$stored_file_paths_file_path"); do \
                    ExtractFileIfArchive current_file; \
                done; \
                ExtractFileIfArchive file; \
            );
        done
    else
        
        if [ ! "$1" = "RUN" ]; then
            files_folders_to_compare=$( \
                if [ -n "$1" ]; then \
                    IFS="$initial_IFS"; \
                    for file; do \
                        ExtractFileIfArchive file; \
                    done; \
                else \
                    IFS='
'; \
                    for file in $(cat "$stored_file_paths_file_path"); do \
                        ExtractFileIfArchive file; \
                    done; \
                fi; \
            );
        fi
        if [ -z "$3" ]; then
            files_folders_to_compare=$( \
                IFS='
'; \
                for current_file in $(cat "$stored_file_paths_file_path"); do \
                    ExtractFileIfArchive current_file; \
                done; \
            );
        fi
        
        input_answer="$2"
        
        if [ -z "$input_answer" ] || [ ! "$1" = "RUN" ]; then
            PrintMenu
            printf '%s\n' "    Press other keys (e.g. arrows) during the first 1 second"
            printf '%s\n' "    to cancel automatically loading the default option ($default_menu_option)..."
            printf '%s'   "    "
        fi>"$print_to_screen"
        
        break_timeout_state="STATE1"
        break_timeout_state="$(PrintSavedBreakTimeoutFromFile)"
        if [ ! "$break_timeout_state" = "STATE3" ]; then
            cat '/dev/null'>"$temp_break_timeout_state_file"
            printf "STATE1">"$temp_break_timeout_state_file"
        else
            printf "STATE2">"$temp_break_timeout_state_file"
        fi
        
        {
            sleep 1;
            break_timeout_state="$(PrintSavedBreakTimeoutFromFile)"
            if [ "$break_timeout_state" = "STATE1" ]; then
                printf "STATE3">"$temp_break_timeout_state_file"
                #stty -F /dev/tty sane
                eval "$current_shell_full_path" \"\$current_script_path\" $OPEN_WITH_MENU RUN "$default_menu_option"
                exit 0
            fi
        }&
        pid=$!
        
        break_timeout_state="$(PrintSavedBreakTimeoutFromFile)"
        
        while [ ! "$break_timeout_state" = "STATE3" ] && [ ! "$input_answer" = "1" ] && [ ! "$input_answer" = "2" ] && [ ! "$input_answer" = "3" ] && [ ! "$input_answer" = "0" ] && [ ! "$input_answer" = "-" ]; do
            input_answer=""
            input_answer=$(get_char)
            if [ "$break_timeout_state" = "STATE1" ]; then
                eval kill -s PIPE $pid>/dev/null 2>/dev/null #kill the background process denoted here by $pid, suppressing "Terminated" message
                break_timeout_state="STATE2"
                printf "STATE2">"$temp_break_timeout_state_file"
            fi
        done
        
        ##
        
        IFS='
'
        
        case $input_answer in
            "1" )
                printf '\n%s\n' "1. diff -r"
                printf '%s\n' "diff -r $files_folders_to_compare"
                printf "\n"
                CheckFilesFoldersToCompare
                if [ "$exit_code" = "0" ]; then
                    printf '%s\n' "compared">"$temp_compared_status_file"
                    IFS='
'
                    diff_output="$(eval diff -r $files_folders_to_compare)"
                    error_code=$?
                    if [ -z "$diff_output" ] && [ "$error_code" = "0" ]; then
                        printf '%s\n' "NO DIFFERENCES ENCOUNTERED..."
                        [ ! "$2" = "1" ] && printf '\n%s\n' "DONE.">"$print_to_screen"
                    else
                        printf '%s\n' "$diff_output"
                        [ ! "$2" = "1" ] && printf '\n%s\n' "DONE.">"$print_to_screen"
                    fi
                fi
                if [ "$default_menu_option" = "1" ]; then if [ ! "$2" = "$default_menu_option" ]; then PrepareExitAndExit; fi; else PrepareExitAndExit; fi
                ;;
            "2" )
                printf '\n%s\n' "2. diff -r -q"
                printf '%s\n' "diff -r -q $files_folders_to_compare"
                #printf "\n"
                CheckFilesFoldersToCompare
                if [ "$exit_code" = "0" ]; then
                    printf '%s\n' "compared">"$temp_compared_status_file"
                    IFS='
'
                    diff_output="$(eval diff -r -q $files_folders_to_compare)"
                    error_code=$?
                    if [ -z "$diff_output" ] && [ "$error_code" = "0" ]; then
                        printf '%s\n' "NO DIFFERENCES ENCOUNTERED..."
                        [ ! "$2" = "2" ] && printf '\n%s\n' "DONE.">"$print_to_screen"
                    else
                        printf '%s\n' "$diff_output"
                        [ ! "$2" = "2" ] && printf '\n%s\n' "DONE.">"$print_to_screen"
                    fi
                fi
                if [ "$default_menu_option" = "2" ]; then if [ ! "$2" = "$default_menu_option" ]; then PrepareExitAndExit; fi; else PrepareExitAndExit; fi
                ;;
            "3" )
                printf '\n%s\n' "3. Meld"
                printf '%s\n' "meld $files_folders_to_compare"
                printf "\n"
                CheckFilesFoldersToCompare
                if [ "$exit_code" = "0" ]; then
                    printf '%s\n' "compared">"$temp_compared_status_file"
                    IFS='
'
                    eval meld $files_folders_to_compare 2>/dev/null||{
                        printf '%s\n' "ERROR: Meld is not installed?">&2
                        {
                        printf '%s\n' "Press Enter to exit...";
                        CleanUp; read temp;
                        }>"$print_to_screen"
                        exit_code=1
                    }
                fi
                if [ "$default_menu_option" = "3" ]; then if [ ! "$2" = "$default_menu_option" ]; then PrepareExitAndExit; fi; else PrepareExitAndExit; fi
                ;;
            "0" | "-" )
                if [ "$input_answer" = "0" ]; then printf "\n">"$print_to_screen"; exit 0; elif [ "$input_answer" = "-" ]; then printf "\n">"$print_to_screen"; kill -s PIPE -- -$$; fi
                ;;
        esac
    fi
fi 2>&1|sed "s/\$/$CR/"
IFS="$initial_IFS"
  1. If not already done: run the script with the --install flag to install the .desktop file (for quick access)

  2. Second step

    1. Right-Click the [ folders/files / office/pdf documents / archives ], choose Open With, and the choose File Comparer.
      -> in order to add these [ folders/files / office/pdf documents / archives ] to the comparison queue

    or:

    1. Run the script with the desired parameters ([ folders/files / office/pdf documents / archives ])

      -> in order to add these [ folders/files / office/pdf documents / archives ] to the comparison queue

  3. (Can be run repeatedly:) Run the script with no parameters in order to do the comparison (the file selection is memorized until running the steps 2.1. / 2.2. again)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .