Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

Suppose we have two directories, dirA, dirB, which the exact same PDF files, just different last modified.

What is a bash script (no awk) that can search through each file name (assume always in both dirA, dirB) and for each filename, outputs which of the files (dirA/file or dirB/file) has the greater last-modified; file-modified-last? e.g.

if dirA/file.lastmodified > dirB/file.lastmodified 
##take action
share|improve this question
    
By 'greater last modified' you mean 'file modified last'? –  schaiba Feb 4 '13 at 9:46
    
updated to respond –  mathStudent Feb 4 '13 at 9:50
    
Chris' answer seems about right. –  schaiba Feb 4 '13 at 9:51
    
What action do you intend to perform afterwards? –  user21228 Feb 5 '13 at 8:42

3 Answers 3

With GNU stat:

shopt -s dotglob

for file in dirA/*; do
    [[ -f "dirB/${file##*/}" ]] || continue
    if (( "$(stat -c %Y "$file")" > "$(stat -c %Y "dirB/${file##*/}")" )); then
        # take action
    fi
done
share|improve this answer
    
zsh, ksh93 and bash have [[ file1 -nt file2 ]] to compare file modification time. You may also need to take into consideration what you want to do with symlinks –  Stéphane Chazelas Feb 4 '13 at 19:33
    
Beware that if the filesystem supports timestamps with a reosolution better than 1 second, this will fail, as stat -c %Y rounds the timestamp to an integer number of seconds. –  Gilles Feb 5 '13 at 0:50

Bash, ksh, zsh and even ash have a -nt operator for the [ builtin (and in bash/ksh/zsh the [[ … ]] construct) that tests whether a file is newer than another.

for x in dirA/*; do
  y=dirB/${x#*/}
  if [ "$x" -nt "$y" ]; then
    # The file in dirA is more recent
  elif [ "$y" -nt "$x" ]
    # The file in dirB is more recent
  else
    # The two files have the same modification time
    # or the file doesn't exist in dirB
  fi
done
share|improve this answer

A possible solution with GNU tools:

find dirA dirB -type f -printf '%T@/%p\0' |
  tr '\n\0\t/' '\0\n/\t' |
  sort -k3 -k1,1rg |
  uniq -f2 |
  cut -f2- |
  tr '\0/\t' '\n\t/'

Would report every file in both dirA and dirB (and their subdirectories) except that if a file is common to both, only the newest (or if they are the same age, any one of them at random).

That only works for values of dirA and dirB like "dirA", that is that don't contain blank or slash characters, though there's no restrictions on the paths of the files they may contain.

With -type f, only regular files are reported (not symlinks, fifos, devices...).

find's -printf, the g sort type, uniq's -f options and the ability of sort, uniq and cut to cope with NUL characters are GNU specific.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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