1

I'm looking for a simple way to have an if statement where the conditional is whether the 2 newest files in a given directory (recursively) are identical in contents.

3
  • This is really two questions in one: (1) get the names of two newest files in a directory (recursive or not? Not clear); (2) compare two files given their paths. (2) is very easy (diff, cmp, etc.). (1) as far as I know is not so easy. There's ls -t, but parsing ls output is always frowned upon; then there's stat, but you might need to manually sort the timestamps.
    – 4ae1e1
    Commented Nov 28, 2015 at 9:12
  • Yes, it is 2 questions in one. And this is why it's not a duplicate of the linked-to question. I could put an answer in a comment, but I think it's worth re-opening the question. After all, I landed here because I had exactly the same question.
    – mivk
    Commented Jun 19, 2018 at 16:43
  • The short answer is: readarray -t files < <(ls -t /your/dir/ | head -2); if diff -q "${files[@]}"; then echo identical; fi. If you are certain that the file names can never contain spaces, you can do the simpler files=$(ls -t /your/dir/ | head -2); if diff -q $files; then echo identical; fi. But one day, there will be a space in a file name...
    – mivk
    Commented Jun 19, 2018 at 17:32

1 Answer 1

0

One way of making the comparison for files contained within a directory in bash without parsing ls is:

unset -v penultimate  ## one before newest
unset -v latest       ## newest

for file in "$dirname"/*; do
    [[ $file -nt $latest ]] && penultimate="$latest" && latest="$file"
done

if [[ -f $latest ]] && [[ -f $penultimate ]]; then
    if diff -q "$penultimate" "$latest" ; then
        printf "Files '%s' and '%s' are identical\n" "$penultimate" "$latest"
    fi
fi

Note: if the files differ, the default behavior of diff -q will output: Files '%s' and '%s' differ\n" "$penultimate" "$latest". Also note, the above compares for the existence of 2 files and not whether either of the newest two are symbolic links. It further does not compare the contents of subdirectories for the given directory.

Not the answer you're looking for? Browse other questions tagged or ask your own question.