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.

How do I create a list of modified files programmatically using linux command line tools? I'm not interested in the difference in any particular file (delta, patch). I just want to have a list of new or modified files comparing to previous product release. So that I can publish a new product update.

update: diff -qr doesn't produce very convinient output. The output of diff -qr also needs to be processed. Is there any better way?

share|improve this question
    
what's an example of "convenient" output? –  frogstarr78 Oct 4 '11 at 4:07
add comment

migrated from stackoverflow.com Oct 3 '11 at 13:24

This question came from our site for professional and enthusiast programmers.

9 Answers

up vote 4 down vote accepted

I`ve got a simple approach for this: Use the rsync-preview mode:

rysnc -aHSvn --delete previous_dir/ new-dir/

The files that are shown as "to be deleted" by that command will be the "new" files. The others that are to be transferred have changed in some way. See the rsync-man-page for further details.

share|improve this answer
add comment

You can use the diff toool: see the options -q and -r

-q  --brief
Output only whether files differ.

-r  --recursive
Recursively compare any subdirectories found.

Example:

diff -qr dir1 dir2
share|improve this answer
add comment

The diffutils package includes a lsdiff tool. Just pass the output of diff -u to lsdiff:

diff -u --other-diff-options path1 path2 | lsdiff
share|improve this answer
    
Good suggestion, thank you. Was in the patchutils package for me (CentOS 5.x). –  Steve Kehlet Oct 18 '12 at 0:54
    
Yep, patchutils package for Ubuntu/Debian, too. –  artfulrobot Mar 6 at 12:56
add comment

I would just touch a file at the time of each update, and then you can find files that were modified since then with find /tree/location -newer /last/update/file -print

share|improve this answer
add comment

To take only the name of files that they changed, I use this command:

diff -r dirt1 dir2 --brief | sed 's/^Only in \([^:]*\): /\1\//' | sed 's/^Files \(.*\) and .* differ/\1/'

If need to exclude some files as object files or library files, you could use:

diff -r dirt1 dir2 --brief --exclude "*.o" --exclude "*.a" | sed 's/^Only in \([^:]*\): /\1\//' | sed 's/^Files \(.*\) and .* differ/\1/'
share|improve this answer
add comment

You should get desired result using:

diff -r --brief dir1/ dir2/
share|improve this answer
add comment

This might do the trick:

compare_dirs()
{
    # Shows which files and directories exist in one directory but not both
    if [ $# -ne 2 ]
    then
        echo "Usage: compare_dirs dir1 dir2" >&2
        return 2
    fi
    for path
    do
        if [ ! -d "$path" ]
        then
            echo "Not a directory: $path" >&2
            return 1
        fi
    done
    comm -3 \
        <(cd -- "$1" && find . -printf '%P\0' | sort -z | quote_shell) \
        <(cd -- "$2" && find . -printf '%P\0' | sort -z | quote_shell)
}
share|improve this answer
add comment

Normally you put the files into some kind of version control system like SubVersion or git, since those can do this for you out of the box.

But you could do a quick script with a for loop on dir1 and then compare every file with the one in dir2. The for loop can look at the exit code from diff to know if the files was different.

Maybe something like this:

for f in `(cd dir1 ; find .)`
do 
  diff $f ../dir2/$f
  if [ "$?" == "0" ]
  then 
    echo same
  else 
    echo diff: $f
  fi
done

Note: Script is not tested, so the above example is "bash inspired pseudocode"...


Let's take another go but with git

Create some example files to play with

mkdir -p dir1/test1/test11
mkdir -p dir1/test1/test12
mkdir -p dir1/test1/test13
echo "Test1" >> dir1/test1/test11/t1.txt
echo "Test2" >> dir1/test1/test12/t2.txt
echo "Test3" >> dir1/test1/test13/t3.txt

#And a dir to work in
mkdir gitdir

Then enter the dir and import dir1

cd gitdir/
git init .
cp -r ../dir1/* .
git add .
git commit -m 'dir1'

Go out and modify dir1 (so it becomes your dir2)

cd ..
echo "Test2" > dir1/test1/test11/t1.txt

Then go into the git dir and import the new dir

cd gitdir/
cp -r ../dir1/* .

Now ask git what has change (with the status command)

git status -s

The output is a list with the changes, that looks like this:

 M test1/test11/t1.txt
share|improve this answer
add comment

Maybe you'd be happier with something different. Try git.

Do this as an example:

mkdir a
cd a
git init
touch b
git add . && git commit -m "Empty file"
git status
echo c >> b
git status
git add . && git commit -m "Full file"
git status

git will track your files for you. The command git status will show you all the files that have been modified since the last commit.

share|improve this answer
add comment

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.