Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented sorting output duplicate files by size #56

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ Usage: fdupes [options] DIRECTORY...
-f --omitfirst omit the first file in each set of matches
-1 --sameline list each set of matches on a single line
-S --size show size of duplicate files
-z --sortbysize sort output by size of duplicate files (descending)
-m --summarize summarize dupe information
-q --quiet hide progress indicator
-d --delete prompt user for files to preserve and delete all
Expand Down
3 changes: 3 additions & 0 deletions fdupes.1
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ list each set of matches on a single line
.B -S --size
show size of duplicate files
.TP
.B -z --sortbysize
sort output by size of duplicate files (descending)
.TP
.B -m --summarize
summarize duplicate files information
.TP
Expand Down
80 changes: 79 additions & 1 deletion fdupes.c
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@
#define F_EXCLUDEHIDDEN 0x1000
#define F_PERMISSIONS 0x2000
#define F_REVERSE 0x4000
#define F_SORTBYSIZE 0x8000

typedef enum {
ORDER_TIME = 0,
Expand Down Expand Up @@ -925,6 +926,76 @@ int sort_pairs_by_filename(file_t *f1, file_t *f2)
return strcmp(f1->d_name, f2->d_name);
}

// function prototype for sorting
file_t* sorted_merge(file_t* a, file_t* b);
void mergesortbysize(file_t** headRef)
{
file_t* head = *headRef;
file_t* slow;
file_t* fast;
file_t* back_head;

// Nothing to sort if length is 0 or 1
if ((head == NULL) || (head->next == NULL))
{
return;
}

// Split in two sublists
slow = head;
fast = head->next;

while (fast != NULL)
{
fast = fast->next;
if (fast != NULL)
{
slow = slow->next;
fast = fast->next;
}
}
back_head = slow->next;
slow->next = NULL;

// Recursively sort the sublists
mergesortbysize(&head);
mergesortbysize(&back_head);

// merge the two sorted sublists
*headRef = sorted_merge(head, back_head);
}

file_t* sorted_merge(file_t* a, file_t* b)
{
file_t* result = NULL;
file_t** tail = &result;

while (a != NULL && b != NULL) {
if (a->size > b->size)
{
*tail = a;
a = a->next;
(*tail)->next = NULL;
tail = &((*tail)->next);
}
else
{
*tail = b;
b = b->next;
(*tail)->next = NULL;
tail = &((*tail)->next);
}
}

// append remaining nonempty list
if (a!= NULL)
*tail = a;
if (b!= NULL)
*tail = b;

return(result);
}

void registerpair(file_t **matchlist, file_t *newmatch,
int (*comparef)(file_t *f1, file_t *f2))
{
Expand Down Expand Up @@ -989,6 +1060,7 @@ void help_text()
printf(" -f --omitfirst \tomit the first file in each set of matches\n");
printf(" -1 --sameline \tlist each set of matches on a single line\n");
printf(" -S --size \tshow size of duplicate files\n");
printf(" -z --sortbysize \tsort output by size of duplicate files (descending)\n");
printf(" -m --summarize \tsummarize dupe information\n");
printf(" -q --quiet \thide progress indicator\n");
printf(" -d --delete \tprompt user for files to preserve and delete all\n");
Expand Down Expand Up @@ -1039,6 +1111,7 @@ int main(int argc, char **argv) {
{ "quiet", 0, 0, 'q' },
{ "sameline", 0, 0, '1' },
{ "size", 0, 0, 'S' },
{ "sortbysize", 0, 0, 'z' },
{ "symlinks", 0, 0, 's' },
{ "hardlinks", 0, 0, 'H' },
{ "relink", 0, 0, 'l' },
Expand All @@ -1064,7 +1137,7 @@ int main(int argc, char **argv) {

oldargv = cloneargs(argc, argv);

while ((opt = GETOPT(argc, argv, "frRq1SsHlnAdvhNmpo:i"
while ((opt = GETOPT(argc, argv, "frRq1SszHlnAdvhNmpo:i"
#ifndef OMIT_GETOPT_LONG
, long_options, NULL
#endif
Expand All @@ -1091,6 +1164,9 @@ int main(int argc, char **argv) {
case 's':
SETFLAG(flags, F_FOLLOWLINKS);
break;
case 'z':
SETFLAG(flags, F_SORTBYSIZE);
break;
case 'H':
SETFLAG(flags, F_CONSIDERHARDLINKS);
break;
Expand Down Expand Up @@ -1229,6 +1305,8 @@ int main(int argc, char **argv) {

if (!ISFLAG(flags, F_HIDEPROGRESS)) fprintf(stderr, "\r%40s\r", " ");

if (ISFLAG(flags, F_SORTBYSIZE)) mergesortbysize(&files);

if (ISFLAG(flags, F_DELETEFILES))
{
if (ISFLAG(flags, F_NOPROMPT))
Expand Down