Comparing the contents of two directories
I have two directories that should contain the same files and have the same directory structure.
I think that something is missing in one of these directories.
Using the bash shell, is there a way to compare my directories and see if one of them is missing files that are present in the other?
command-line
add a comment |
I have two directories that should contain the same files and have the same directory structure.
I think that something is missing in one of these directories.
Using the bash shell, is there a way to compare my directories and see if one of them is missing files that are present in the other?
command-line
1
What is the output ofbash --version
?
– jobin
Feb 16 '14 at 17:10
1
Similar but more specific: stackoverflow.com/questions/16787916/…
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Apr 9 '15 at 8:32
add a comment |
I have two directories that should contain the same files and have the same directory structure.
I think that something is missing in one of these directories.
Using the bash shell, is there a way to compare my directories and see if one of them is missing files that are present in the other?
command-line
I have two directories that should contain the same files and have the same directory structure.
I think that something is missing in one of these directories.
Using the bash shell, is there a way to compare my directories and see if one of them is missing files that are present in the other?
command-line
command-line
edited Apr 27 '15 at 23:53
Braiam
51.5k20136220
51.5k20136220
asked Feb 16 '14 at 16:54
AndreaNobiliAndreaNobili
93141622
93141622
1
What is the output ofbash --version
?
– jobin
Feb 16 '14 at 17:10
1
Similar but more specific: stackoverflow.com/questions/16787916/…
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Apr 9 '15 at 8:32
add a comment |
1
What is the output ofbash --version
?
– jobin
Feb 16 '14 at 17:10
1
Similar but more specific: stackoverflow.com/questions/16787916/…
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Apr 9 '15 at 8:32
1
1
What is the output of
bash --version
?– jobin
Feb 16 '14 at 17:10
What is the output of
bash --version
?– jobin
Feb 16 '14 at 17:10
1
1
Similar but more specific: stackoverflow.com/questions/16787916/…
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Apr 9 '15 at 8:32
Similar but more specific: stackoverflow.com/questions/16787916/…
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Apr 9 '15 at 8:32
add a comment |
9 Answers
9
active
oldest
votes
A good way to do this comparison is to use find
with md5sum
, then a diff
.
Example
Use find to list all the files in the directory then calculate the md5 hash for each file and pipe it sorted by filename to a file:
find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt
Do the same procedure to the another directory:
find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt
Then compare the result two files with diff
:
diff -u dir1.txt dir2.txt
Or as a single command using process substitution:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)
If you want to see only the changes:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")
The cut command prints only the hash (first field) to be compared by diff. Otherwise diff will print every line as the directory paths differ even when the hash is the same.
But you won't know which file changed...
For that, you can try something like
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /')
This strategy is very useful when the two directories to be compared are not in the same machine and you need to make sure that the files are equal in both directories.
Another good way to do the job is using Git’s diff
command (may cause problems when files has different permissions -> every file is listed in output then):
git diff --no-index dir1/ dir2/
1
This doesn't work without an extra sorting step, because the order in whichfind
will list the files will differ in general between the two directories.
– Faheem Mitha
Aug 30 '17 at 10:22
1
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
1
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
1
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
|
show 2 more comments
You can use the diff
command just as you would use it for files:
diff <directory1> <directory2>
If you want to see subfolders and -files too, you can use the -r
option:
diff -r <directory1> <directory2>
2
Didn't knowdiff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.
– jobin
Feb 16 '14 at 17:04
1
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
1
I have something like this:a/b/c/d/a
,x/b/c/d/b
. See whatdiff a x
gives you.
– jobin
Feb 16 '14 at 17:09
2
You have to use the-r
option. That (diff -r a x
) gives me:Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
3
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
|
show 4 more comments
Through you are not using bash, you can do it using diff with --brief
and --recursive
:
$ diff -rq dir1 dir2
Only in dir2: file2
Only in dir1: file1
The man diff
includes both options:
-q
,--brief
report only when files differ
-r
,--recursive
recursively compare any subdirectories found
add a comment |
Here is an alternative, to compare just filenames, and not their contents:
diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)
This is an easy way to list missing files, but of course it won't detect files with the same name but different contents!
(Personally I use my own diffdirs
script, but that is part of a larger library.)
3
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
3
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIKdiff
is not supporting as of now. But there iscomm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can docomm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the--output-delimiter
parameter and additional tools).
– phk
Mar 5 '16 at 21:52
add a comment |
If you want to make each file expandable and collapsible, you can pipe the output of diff -r
into Vim.
First let's give Vim a folding rule:
mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim
Now just:
diff -r dir1 dir2 | vim -
You can hit zo
and zc
to open and close folds. To get out of Vim, hit :q<Enter>
add a comment |
Fairly easy task to achieve in python:
python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2
Substitute actual values for DIR1
and DIR2
.
Here's sample run:
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF
For readability, here's an actual script instead of one-liner:
#!/usr/bin/env python
import os, sys
d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()
if d1 == d2:
print("SAME")
else:
print("DIFF")
2
Note that theos.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.
– muru
Nov 14 '16 at 6:15
1
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
add a comment |
Maybe one option is to run rsync two times
rsync -r -n -t -v --progress -c -s /dir1/ /dir2/
With the previous line, you will get files that are in dir1 and are different (or missing) in dir2. Also folders with different date.
rsync -r -n -t -v --progress -c -s /dir2/ /dir1/
The same for dir2
#from the rsync --help :
-r, --recursive recurse into directories
-n, --dry-run perform a trial run with no changes made
-t, --times preserve modification times
-v, --verbose increase verbosity
--progress show progress during transfer
-c, --checksum skip based on checksum, not mod-time & size
-s, --protect-args no space-splitting; only wildcard special-chars
You can delete the -n option to undergo the changes. That is copying the list of files to the second folder.
In case you do that, maybe a good option is to use -u, to avoid overwriting newer files.
-u, --update skip files that are newer on the receiver
add a comment |
Inspired by Sergiy's reply, I wrote my own Python script to compare two directories.
Unlike many other solutions it doesn't compare contents of the files. Also it doesn't go inside subdirectories which are missing in one of the directories. So the output is quite concise and the script works fast with large directories.
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs =
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
If you save it to a file named compare_dirs.py
, you can run it with Python3.x:
python3 compare_dirs.py dir1 dir2
Sample output:
user@laptop:~$ python3 compare_dirs.py old/ new/
DIR old/out/flavor-domino removed
DIR new/out/flavor-maxim2 added
DIR old/target/vendor/flavor-domino removed
DIR new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR new/tools/tools/LiveSuit_For_Linux64 added
P.S. If you need to compare file sizes and file hashes for potential changes, I published an updated script here: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
1
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
add a comment |
I'll add to this list a NodeJs alternative that I've written some time ago.
dir-compare
npm install dir-compare -g
dircompare dir1 dir2
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "89"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f421712%2fcomparing-the-contents-of-two-directories%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
9 Answers
9
active
oldest
votes
9 Answers
9
active
oldest
votes
active
oldest
votes
active
oldest
votes
A good way to do this comparison is to use find
with md5sum
, then a diff
.
Example
Use find to list all the files in the directory then calculate the md5 hash for each file and pipe it sorted by filename to a file:
find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt
Do the same procedure to the another directory:
find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt
Then compare the result two files with diff
:
diff -u dir1.txt dir2.txt
Or as a single command using process substitution:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)
If you want to see only the changes:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")
The cut command prints only the hash (first field) to be compared by diff. Otherwise diff will print every line as the directory paths differ even when the hash is the same.
But you won't know which file changed...
For that, you can try something like
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /')
This strategy is very useful when the two directories to be compared are not in the same machine and you need to make sure that the files are equal in both directories.
Another good way to do the job is using Git’s diff
command (may cause problems when files has different permissions -> every file is listed in output then):
git diff --no-index dir1/ dir2/
1
This doesn't work without an extra sorting step, because the order in whichfind
will list the files will differ in general between the two directories.
– Faheem Mitha
Aug 30 '17 at 10:22
1
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
1
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
1
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
|
show 2 more comments
A good way to do this comparison is to use find
with md5sum
, then a diff
.
Example
Use find to list all the files in the directory then calculate the md5 hash for each file and pipe it sorted by filename to a file:
find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt
Do the same procedure to the another directory:
find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt
Then compare the result two files with diff
:
diff -u dir1.txt dir2.txt
Or as a single command using process substitution:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)
If you want to see only the changes:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")
The cut command prints only the hash (first field) to be compared by diff. Otherwise diff will print every line as the directory paths differ even when the hash is the same.
But you won't know which file changed...
For that, you can try something like
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /')
This strategy is very useful when the two directories to be compared are not in the same machine and you need to make sure that the files are equal in both directories.
Another good way to do the job is using Git’s diff
command (may cause problems when files has different permissions -> every file is listed in output then):
git diff --no-index dir1/ dir2/
1
This doesn't work without an extra sorting step, because the order in whichfind
will list the files will differ in general between the two directories.
– Faheem Mitha
Aug 30 '17 at 10:22
1
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
1
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
1
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
|
show 2 more comments
A good way to do this comparison is to use find
with md5sum
, then a diff
.
Example
Use find to list all the files in the directory then calculate the md5 hash for each file and pipe it sorted by filename to a file:
find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt
Do the same procedure to the another directory:
find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt
Then compare the result two files with diff
:
diff -u dir1.txt dir2.txt
Or as a single command using process substitution:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)
If you want to see only the changes:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")
The cut command prints only the hash (first field) to be compared by diff. Otherwise diff will print every line as the directory paths differ even when the hash is the same.
But you won't know which file changed...
For that, you can try something like
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /')
This strategy is very useful when the two directories to be compared are not in the same machine and you need to make sure that the files are equal in both directories.
Another good way to do the job is using Git’s diff
command (may cause problems when files has different permissions -> every file is listed in output then):
git diff --no-index dir1/ dir2/
A good way to do this comparison is to use find
with md5sum
, then a diff
.
Example
Use find to list all the files in the directory then calculate the md5 hash for each file and pipe it sorted by filename to a file:
find /dir1/ -type f -exec md5sum {} + | sort -k 2 > dir1.txt
Do the same procedure to the another directory:
find /dir2/ -type f -exec md5sum {} + | sort -k 2 > dir2.txt
Then compare the result two files with diff
:
diff -u dir1.txt dir2.txt
Or as a single command using process substitution:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2) <(find /dir2/ -type f -exec md5sum {} + | sort -k 2)
If you want to see only the changes:
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ") <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | cut -f1 -d" ")
The cut command prints only the hash (first field) to be compared by diff. Otherwise diff will print every line as the directory paths differ even when the hash is the same.
But you won't know which file changed...
For that, you can try something like
diff <(find /dir1/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /') <(find /dir2/ -type f -exec md5sum {} + | sort -k 2 | sed 's/ .*// /')
This strategy is very useful when the two directories to be compared are not in the same machine and you need to make sure that the files are equal in both directories.
Another good way to do the job is using Git’s diff
command (may cause problems when files has different permissions -> every file is listed in output then):
git diff --no-index dir1/ dir2/
edited Dec 9 '18 at 9:09
Zanna
50.4k13133241
50.4k13133241
answered Jan 9 '17 at 20:05
Adail JuniorAdail Junior
67654
67654
1
This doesn't work without an extra sorting step, because the order in whichfind
will list the files will differ in general between the two directories.
– Faheem Mitha
Aug 30 '17 at 10:22
1
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
1
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
1
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
|
show 2 more comments
1
This doesn't work without an extra sorting step, because the order in whichfind
will list the files will differ in general between the two directories.
– Faheem Mitha
Aug 30 '17 at 10:22
1
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
1
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
1
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
1
1
This doesn't work without an extra sorting step, because the order in which
find
will list the files will differ in general between the two directories.– Faheem Mitha
Aug 30 '17 at 10:22
This doesn't work without an extra sorting step, because the order in which
find
will list the files will differ in general between the two directories.– Faheem Mitha
Aug 30 '17 at 10:22
1
1
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
One can use the method described in askubuntu.com/a/662383/15729 to sort the files.
– Faheem Mitha
Aug 30 '17 at 10:48
1
1
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
I get the error ``find: md5sum: No such file or directory
– Houman
Oct 3 '17 at 13:14
1
1
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@Houman I don't know what Linux Distro you are using, but perhaps you need to install a package that will provide de md5sum. In Fedora 26 you can install it with: #dnf install coreutils
– Adail Junior
Oct 4 '17 at 19:05
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
@AdailJunior I'm on Mac Sierra. Thanks
– Houman
Oct 5 '17 at 12:26
|
show 2 more comments
You can use the diff
command just as you would use it for files:
diff <directory1> <directory2>
If you want to see subfolders and -files too, you can use the -r
option:
diff -r <directory1> <directory2>
2
Didn't knowdiff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.
– jobin
Feb 16 '14 at 17:04
1
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
1
I have something like this:a/b/c/d/a
,x/b/c/d/b
. See whatdiff a x
gives you.
– jobin
Feb 16 '14 at 17:09
2
You have to use the-r
option. That (diff -r a x
) gives me:Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
3
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
|
show 4 more comments
You can use the diff
command just as you would use it for files:
diff <directory1> <directory2>
If you want to see subfolders and -files too, you can use the -r
option:
diff -r <directory1> <directory2>
2
Didn't knowdiff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.
– jobin
Feb 16 '14 at 17:04
1
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
1
I have something like this:a/b/c/d/a
,x/b/c/d/b
. See whatdiff a x
gives you.
– jobin
Feb 16 '14 at 17:09
2
You have to use the-r
option. That (diff -r a x
) gives me:Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
3
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
|
show 4 more comments
You can use the diff
command just as you would use it for files:
diff <directory1> <directory2>
If you want to see subfolders and -files too, you can use the -r
option:
diff -r <directory1> <directory2>
You can use the diff
command just as you would use it for files:
diff <directory1> <directory2>
If you want to see subfolders and -files too, you can use the -r
option:
diff -r <directory1> <directory2>
answered Feb 16 '14 at 16:59
Alex R.Alex R.
909158
909158
2
Didn't knowdiff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.
– jobin
Feb 16 '14 at 17:04
1
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
1
I have something like this:a/b/c/d/a
,x/b/c/d/b
. See whatdiff a x
gives you.
– jobin
Feb 16 '14 at 17:09
2
You have to use the-r
option. That (diff -r a x
) gives me:Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
3
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
|
show 4 more comments
2
Didn't knowdiff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.
– jobin
Feb 16 '14 at 17:04
1
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
1
I have something like this:a/b/c/d/a
,x/b/c/d/b
. See whatdiff a x
gives you.
– jobin
Feb 16 '14 at 17:09
2
You have to use the-r
option. That (diff -r a x
) gives me:Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
3
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
2
2
Didn't know
diff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.– jobin
Feb 16 '14 at 17:04
Didn't know
diff
works for directories as well(man diff confirmed that), but this doesn't recursively check for changes in subdirectories inside subdirectories.– jobin
Feb 16 '14 at 17:04
1
1
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
@Jobin That's strange... For me, it does work.
– Alex R.
Feb 16 '14 at 17:07
1
1
I have something like this:
a/b/c/d/a
, x/b/c/d/b
. See what diff a x
gives you.– jobin
Feb 16 '14 at 17:09
I have something like this:
a/b/c/d/a
, x/b/c/d/b
. See what diff a x
gives you.– jobin
Feb 16 '14 at 17:09
2
2
You have to use the
-r
option. That (diff -r a x
) gives me: Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
You have to use the
-r
option. That (diff -r a x
) gives me: Only in a/b/c/d: a. only in x/b/c/d: b.
– Alex R.
Feb 16 '14 at 17:11
3
3
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
diff show me the difference INTO files but not if a directory contains a file that the other one not contains !!! I don't need know the differences into file but also if a file exist in a directory and not in the other one
– AndreaNobili
Feb 16 '14 at 17:17
|
show 4 more comments
Through you are not using bash, you can do it using diff with --brief
and --recursive
:
$ diff -rq dir1 dir2
Only in dir2: file2
Only in dir1: file1
The man diff
includes both options:
-q
,--brief
report only when files differ
-r
,--recursive
recursively compare any subdirectories found
add a comment |
Through you are not using bash, you can do it using diff with --brief
and --recursive
:
$ diff -rq dir1 dir2
Only in dir2: file2
Only in dir1: file1
The man diff
includes both options:
-q
,--brief
report only when files differ
-r
,--recursive
recursively compare any subdirectories found
add a comment |
Through you are not using bash, you can do it using diff with --brief
and --recursive
:
$ diff -rq dir1 dir2
Only in dir2: file2
Only in dir1: file1
The man diff
includes both options:
-q
,--brief
report only when files differ
-r
,--recursive
recursively compare any subdirectories found
Through you are not using bash, you can do it using diff with --brief
and --recursive
:
$ diff -rq dir1 dir2
Only in dir2: file2
Only in dir1: file1
The man diff
includes both options:
-q
,--brief
report only when files differ
-r
,--recursive
recursively compare any subdirectories found
answered Feb 16 '14 at 21:19
BraiamBraiam
51.5k20136220
51.5k20136220
add a comment |
add a comment |
Here is an alternative, to compare just filenames, and not their contents:
diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)
This is an easy way to list missing files, but of course it won't detect files with the same name but different contents!
(Personally I use my own diffdirs
script, but that is part of a larger library.)
3
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
3
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIKdiff
is not supporting as of now. But there iscomm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can docomm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the--output-delimiter
parameter and additional tools).
– phk
Mar 5 '16 at 21:52
add a comment |
Here is an alternative, to compare just filenames, and not their contents:
diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)
This is an easy way to list missing files, but of course it won't detect files with the same name but different contents!
(Personally I use my own diffdirs
script, but that is part of a larger library.)
3
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
3
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIKdiff
is not supporting as of now. But there iscomm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can docomm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the--output-delimiter
parameter and additional tools).
– phk
Mar 5 '16 at 21:52
add a comment |
Here is an alternative, to compare just filenames, and not their contents:
diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)
This is an easy way to list missing files, but of course it won't detect files with the same name but different contents!
(Personally I use my own diffdirs
script, but that is part of a larger library.)
Here is an alternative, to compare just filenames, and not their contents:
diff <(cd folder1 && find . | sort) <(cd folder2 && find . | sort)
This is an easy way to list missing files, but of course it won't detect files with the same name but different contents!
(Personally I use my own diffdirs
script, but that is part of a larger library.)
edited Feb 17 '14 at 5:15
answered Feb 16 '14 at 17:35
joeytwiddlejoeytwiddle
9141021
9141021
3
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
3
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIKdiff
is not supporting as of now. But there iscomm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can docomm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the--output-delimiter
parameter and additional tools).
– phk
Mar 5 '16 at 21:52
add a comment |
3
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
3
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIKdiff
is not supporting as of now. But there iscomm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can docomm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the--output-delimiter
parameter and additional tools).
– phk
Mar 5 '16 at 21:52
3
3
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
You'd better use process substitution, not temp files...
– mniip
Feb 16 '14 at 18:03
3
3
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIK
diff
is not supporting as of now. But there is comm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can do comm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the --output-delimiter
parameter and additional tools).– phk
Mar 5 '16 at 21:52
Note that this does not support file names with certain special characters, in that case you might want to use zero-delimiters which AFAIK
diff
is not supporting as of now. But there is comm
which is supporting it since git.savannah.gnu.org/cgit/coreutils.git/commit/… so once it comes to a coreutils near you, you can do comm -z <(cd folder1 && find -print0 | sort) <(cd folder2 && find -print0 | sort -z)
(whose output you might have to further convert in the format you need using the --output-delimiter
parameter and additional tools).– phk
Mar 5 '16 at 21:52
add a comment |
If you want to make each file expandable and collapsible, you can pipe the output of diff -r
into Vim.
First let's give Vim a folding rule:
mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim
Now just:
diff -r dir1 dir2 | vim -
You can hit zo
and zc
to open and close folds. To get out of Vim, hit :q<Enter>
add a comment |
If you want to make each file expandable and collapsible, you can pipe the output of diff -r
into Vim.
First let's give Vim a folding rule:
mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim
Now just:
diff -r dir1 dir2 | vim -
You can hit zo
and zc
to open and close folds. To get out of Vim, hit :q<Enter>
add a comment |
If you want to make each file expandable and collapsible, you can pipe the output of diff -r
into Vim.
First let's give Vim a folding rule:
mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim
Now just:
diff -r dir1 dir2 | vim -
You can hit zo
and zc
to open and close folds. To get out of Vim, hit :q<Enter>
If you want to make each file expandable and collapsible, you can pipe the output of diff -r
into Vim.
First let's give Vim a folding rule:
mkdir -p ~/.vim/ftplugin
echo "set foldexpr=getline(v:lnum)=~'^diff.*'?'>1':1 foldmethod=expr fdc=2" >> ~/.vim/ftplugin/diff.vim
Now just:
diff -r dir1 dir2 | vim -
You can hit zo
and zc
to open and close folds. To get out of Vim, hit :q<Enter>
edited Apr 13 '17 at 12:23
Community♦
1
1
answered Mar 6 '16 at 4:25
joeytwiddlejoeytwiddle
9141021
9141021
add a comment |
add a comment |
Fairly easy task to achieve in python:
python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2
Substitute actual values for DIR1
and DIR2
.
Here's sample run:
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF
For readability, here's an actual script instead of one-liner:
#!/usr/bin/env python
import os, sys
d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()
if d1 == d2:
print("SAME")
else:
print("DIFF")
2
Note that theos.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.
– muru
Nov 14 '16 at 6:15
1
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
add a comment |
Fairly easy task to achieve in python:
python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2
Substitute actual values for DIR1
and DIR2
.
Here's sample run:
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF
For readability, here's an actual script instead of one-liner:
#!/usr/bin/env python
import os, sys
d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()
if d1 == d2:
print("SAME")
else:
print("DIFF")
2
Note that theos.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.
– muru
Nov 14 '16 at 6:15
1
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
add a comment |
Fairly easy task to achieve in python:
python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2
Substitute actual values for DIR1
and DIR2
.
Here's sample run:
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF
For readability, here's an actual script instead of one-liner:
#!/usr/bin/env python
import os, sys
d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()
if d1 == d2:
print("SAME")
else:
print("DIFF")
Fairly easy task to achieve in python:
python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' DIR1 DIR2
Substitute actual values for DIR1
and DIR2
.
Here's sample run:
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Desktop
SAME
$ python -c 'import os,sys;d1=os.listdir(sys.argv[1]);d2=os.listdir(sys.argv[2]);d1.sort();d2.sort();x="SAME" if d1 == d2 else "DIFF";print x' Desktop/ Pictures/
DIFF
For readability, here's an actual script instead of one-liner:
#!/usr/bin/env python
import os, sys
d1 = os.listdir(sys.argv[1])
d2 = os.listdir(sys.argv[2])
d1.sort()
d2.sort()
if d1 == d2:
print("SAME")
else:
print("DIFF")
edited Nov 14 '16 at 6:23
answered Nov 14 '16 at 6:12
Sergiy KolodyazhnyySergiy Kolodyazhnyy
70.5k9146309
70.5k9146309
2
Note that theos.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.
– muru
Nov 14 '16 at 6:15
1
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
add a comment |
2
Note that theos.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.
– muru
Nov 14 '16 at 6:15
1
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
2
2
Note that the
os.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.– muru
Nov 14 '16 at 6:15
Note that the
os.listdir
doesn't give any specific order. So the lists might have the same things in different order and the comparison would fail.– muru
Nov 14 '16 at 6:15
1
1
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
@muru good point, I'll include sorting to that
– Sergiy Kolodyazhnyy
Nov 14 '16 at 6:17
add a comment |
Maybe one option is to run rsync two times
rsync -r -n -t -v --progress -c -s /dir1/ /dir2/
With the previous line, you will get files that are in dir1 and are different (or missing) in dir2. Also folders with different date.
rsync -r -n -t -v --progress -c -s /dir2/ /dir1/
The same for dir2
#from the rsync --help :
-r, --recursive recurse into directories
-n, --dry-run perform a trial run with no changes made
-t, --times preserve modification times
-v, --verbose increase verbosity
--progress show progress during transfer
-c, --checksum skip based on checksum, not mod-time & size
-s, --protect-args no space-splitting; only wildcard special-chars
You can delete the -n option to undergo the changes. That is copying the list of files to the second folder.
In case you do that, maybe a good option is to use -u, to avoid overwriting newer files.
-u, --update skip files that are newer on the receiver
add a comment |
Maybe one option is to run rsync two times
rsync -r -n -t -v --progress -c -s /dir1/ /dir2/
With the previous line, you will get files that are in dir1 and are different (or missing) in dir2. Also folders with different date.
rsync -r -n -t -v --progress -c -s /dir2/ /dir1/
The same for dir2
#from the rsync --help :
-r, --recursive recurse into directories
-n, --dry-run perform a trial run with no changes made
-t, --times preserve modification times
-v, --verbose increase verbosity
--progress show progress during transfer
-c, --checksum skip based on checksum, not mod-time & size
-s, --protect-args no space-splitting; only wildcard special-chars
You can delete the -n option to undergo the changes. That is copying the list of files to the second folder.
In case you do that, maybe a good option is to use -u, to avoid overwriting newer files.
-u, --update skip files that are newer on the receiver
add a comment |
Maybe one option is to run rsync two times
rsync -r -n -t -v --progress -c -s /dir1/ /dir2/
With the previous line, you will get files that are in dir1 and are different (or missing) in dir2. Also folders with different date.
rsync -r -n -t -v --progress -c -s /dir2/ /dir1/
The same for dir2
#from the rsync --help :
-r, --recursive recurse into directories
-n, --dry-run perform a trial run with no changes made
-t, --times preserve modification times
-v, --verbose increase verbosity
--progress show progress during transfer
-c, --checksum skip based on checksum, not mod-time & size
-s, --protect-args no space-splitting; only wildcard special-chars
You can delete the -n option to undergo the changes. That is copying the list of files to the second folder.
In case you do that, maybe a good option is to use -u, to avoid overwriting newer files.
-u, --update skip files that are newer on the receiver
Maybe one option is to run rsync two times
rsync -r -n -t -v --progress -c -s /dir1/ /dir2/
With the previous line, you will get files that are in dir1 and are different (or missing) in dir2. Also folders with different date.
rsync -r -n -t -v --progress -c -s /dir2/ /dir1/
The same for dir2
#from the rsync --help :
-r, --recursive recurse into directories
-n, --dry-run perform a trial run with no changes made
-t, --times preserve modification times
-v, --verbose increase verbosity
--progress show progress during transfer
-c, --checksum skip based on checksum, not mod-time & size
-s, --protect-args no space-splitting; only wildcard special-chars
You can delete the -n option to undergo the changes. That is copying the list of files to the second folder.
In case you do that, maybe a good option is to use -u, to avoid overwriting newer files.
-u, --update skip files that are newer on the receiver
edited Dec 17 '17 at 0:17
answered Dec 16 '17 at 23:26
FerroaoFerroao
1379
1379
add a comment |
add a comment |
Inspired by Sergiy's reply, I wrote my own Python script to compare two directories.
Unlike many other solutions it doesn't compare contents of the files. Also it doesn't go inside subdirectories which are missing in one of the directories. So the output is quite concise and the script works fast with large directories.
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs =
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
If you save it to a file named compare_dirs.py
, you can run it with Python3.x:
python3 compare_dirs.py dir1 dir2
Sample output:
user@laptop:~$ python3 compare_dirs.py old/ new/
DIR old/out/flavor-domino removed
DIR new/out/flavor-maxim2 added
DIR old/target/vendor/flavor-domino removed
DIR new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR new/tools/tools/LiveSuit_For_Linux64 added
P.S. If you need to compare file sizes and file hashes for potential changes, I published an updated script here: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
1
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
add a comment |
Inspired by Sergiy's reply, I wrote my own Python script to compare two directories.
Unlike many other solutions it doesn't compare contents of the files. Also it doesn't go inside subdirectories which are missing in one of the directories. So the output is quite concise and the script works fast with large directories.
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs =
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
If you save it to a file named compare_dirs.py
, you can run it with Python3.x:
python3 compare_dirs.py dir1 dir2
Sample output:
user@laptop:~$ python3 compare_dirs.py old/ new/
DIR old/out/flavor-domino removed
DIR new/out/flavor-maxim2 added
DIR old/target/vendor/flavor-domino removed
DIR new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR new/tools/tools/LiveSuit_For_Linux64 added
P.S. If you need to compare file sizes and file hashes for potential changes, I published an updated script here: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
1
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
add a comment |
Inspired by Sergiy's reply, I wrote my own Python script to compare two directories.
Unlike many other solutions it doesn't compare contents of the files. Also it doesn't go inside subdirectories which are missing in one of the directories. So the output is quite concise and the script works fast with large directories.
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs =
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
If you save it to a file named compare_dirs.py
, you can run it with Python3.x:
python3 compare_dirs.py dir1 dir2
Sample output:
user@laptop:~$ python3 compare_dirs.py old/ new/
DIR old/out/flavor-domino removed
DIR new/out/flavor-maxim2 added
DIR old/target/vendor/flavor-domino removed
DIR new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR new/tools/tools/LiveSuit_For_Linux64 added
P.S. If you need to compare file sizes and file hashes for potential changes, I published an updated script here: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
Inspired by Sergiy's reply, I wrote my own Python script to compare two directories.
Unlike many other solutions it doesn't compare contents of the files. Also it doesn't go inside subdirectories which are missing in one of the directories. So the output is quite concise and the script works fast with large directories.
#!/usr/bin/env python3
import os, sys
def compare_dirs(d1: "old directory name", d2: "new directory name"):
def print_local(a, msg):
print('DIR ' if a[2] else 'FILE', a[1], msg)
# ensure validity
for d in [d1,d2]:
if not os.path.isdir(d):
raise ValueError("not a directory: " + d)
# get relative path
l1 = [(x,os.path.join(d1,x)) for x in os.listdir(d1)]
l2 = [(x,os.path.join(d2,x)) for x in os.listdir(d2)]
# determine type: directory or file?
l1 = sorted([(x,y,os.path.isdir(y)) for x,y in l1])
l2 = sorted([(x,y,os.path.isdir(y)) for x,y in l2])
i1 = i2 = 0
common_dirs =
while i1<len(l1) and i2<len(l2):
if l1[i1][0] == l2[i2][0]: # same name
if l1[i1][2] == l2[i2][2]: # same type
if l1[i1][2]: # remember this folder for recursion
common_dirs.append((l1[i1][1], l2[i2][1]))
else:
print_local(l1[i1],'type changed')
i1 += 1
i2 += 1
elif l1[i1][0]<l2[i2][0]:
print_local(l1[i1],'removed')
i1 += 1
elif l1[i1][0]>l2[i2][0]:
print_local(l2[i2],'added')
i2 += 1
while i1<len(l1):
print_local(l1[i1],'removed')
i1 += 1
while i2<len(l2):
print_local(l2[i2],'added')
i2 += 1
# compare subfolders recursively
for sd1,sd2 in common_dirs:
compare_dirs(sd1, sd2)
if __name__=="__main__":
compare_dirs(sys.argv[1], sys.argv[2])
If you save it to a file named compare_dirs.py
, you can run it with Python3.x:
python3 compare_dirs.py dir1 dir2
Sample output:
user@laptop:~$ python3 compare_dirs.py old/ new/
DIR old/out/flavor-domino removed
DIR new/out/flavor-maxim2 added
DIR old/target/vendor/flavor-domino removed
DIR new/target/vendor/flavor-maxim2 added
FILE old/tmp/.kconfig-flavor_domino removed
FILE new/tmp/.kconfig-flavor_maxim2 added
DIR new/tools/tools/LiveSuit_For_Linux64 added
P.S. If you need to compare file sizes and file hashes for potential changes, I published an updated script here: https://gist.github.com/amakukha/f489cbde2afd32817f8e866cf4abe779
edited Aug 9 '18 at 6:42
answered Jan 16 '18 at 10:01
Andriy MakukhaAndriy Makukha
1314
1314
1
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
add a comment |
1
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
1
1
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:
cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
Thanks, I added an optional third param regexp to skip/ignore gist.github.com/mscalora/e86e2bbfd3c24a7c1784f3d692b1c684 to make just what I needed like:
cmpdirs dir1 dir2 '/.git/'
– Mike
Feb 18 '18 at 22:15
add a comment |
I'll add to this list a NodeJs alternative that I've written some time ago.
dir-compare
npm install dir-compare -g
dircompare dir1 dir2
add a comment |
I'll add to this list a NodeJs alternative that I've written some time ago.
dir-compare
npm install dir-compare -g
dircompare dir1 dir2
add a comment |
I'll add to this list a NodeJs alternative that I've written some time ago.
dir-compare
npm install dir-compare -g
dircompare dir1 dir2
I'll add to this list a NodeJs alternative that I've written some time ago.
dir-compare
npm install dir-compare -g
dircompare dir1 dir2
answered Feb 20 '18 at 20:51
gliviugliviu
111
111
add a comment |
add a comment |
Thanks for contributing an answer to Ask Ubuntu!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2faskubuntu.com%2fquestions%2f421712%2fcomparing-the-contents-of-two-directories%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
What is the output of
bash --version
?– jobin
Feb 16 '14 at 17:10
1
Similar but more specific: stackoverflow.com/questions/16787916/…
– Ciro Santilli 新疆改造中心 六四事件 法轮功
Apr 9 '15 at 8:32