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

Add option to preserve file using provided string #144

Closed
wants to merge 1 commit into from
Closed
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 @@ -40,6 +40,7 @@ Usage: fdupes [options] DIRECTORY...
prompting the user
-I --immediate delete duplicates as they are encountered, without
grouping into sets; implies --noprompt
-e --prefer=STRING prefer to keep a file which full pathname contains STRING
-p --permissions don't consider files with different owner/group or
permission bits as duplicates
-o --order=BY select sort order for output and deleting; by file
Expand Down
3 changes: 3 additions & 0 deletions fdupes.1
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,9 @@ set of duplicates and delete the others without prompting the user
delete duplicates as they are encountered, without
grouping into sets; implies --noprompt
.TP
.B -e --prefer\fR=\fISTRING\fR
prefer to keep a file which full pathname contains STRING
.TP
.B -p --permissions
don't consider files with different owner/group or permission bits as duplicates
.TP
Expand Down
111 changes: 67 additions & 44 deletions fdupes.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ typedef enum {

char *program_name;

char *preserved_word;

ordertype_t ordertype = ORDER_MTIME;

#define CHUNK_SIZE 8192
Expand Down Expand Up @@ -960,8 +962,22 @@ void deletefiles(file_t *files, int prompt, FILE *tty, char *logfile)

if (!prompt) /* preserve only the first file */
{
preserve[1] = 1;
for (x = 2; x <= counter; x++) preserve[x] = 0;
if (ISFLAG(flags, F_PREFER))
{
int check = 0;
for (x = 1; x <= counter; x++) {
if (strstr(dupelist[x]->d_name, preserved_word) && check == 0)
preserve[x] = 1;
else
preserve[x] = 0;
check += preserve[x];
}
/* make sure preserve one file */
if (check == 0) preserve[1] = 1;
} else {
preserve[1] = 1;
for (x = 2; x <= counter; x++) preserve[x] = 0;
}
}

else /* prompt for files to preserve */
Expand Down Expand Up @@ -1207,49 +1223,51 @@ void help_text()
{
printf("Usage: fdupes [options] DIRECTORY...\n\n");

printf(" -r --recurse \tfor every directory given follow subdirectories\n");
printf(" \tencountered within\n");
printf(" -R --recurse: \tfor each directory given after this option follow\n");
printf(" \tsubdirectories encountered within (note the ':' at\n");
printf(" \tthe end of the option, manpage for more details)\n");
printf(" -s --symlinks \tfollow symlinks\n");
printf(" -H --hardlinks \tnormally, when two or more files point to the same\n");
printf(" \tdisk area they are treated as non-duplicates; this\n");
printf(" \toption will change this behavior\n");
printf(" -G --minsize=SIZE\tconsider only files greater than or equal to SIZE\n");
printf(" -L --maxsize=SIZE\tconsider only files less than or equal to SIZE\n");
printf(" -n --noempty \texclude zero-length files from consideration\n");
printf(" -A --nohidden \texclude hidden files from consideration\n");
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(" -t --time \tshow modification time of duplicate files\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");
printf(" \tothers; important: under particular circumstances,\n");
printf(" \tdata may be lost when using this option together\n");
printf(" \twith -s or --symlinks, or when specifying a\n");
printf(" \tparticular directory more than once; refer to the\n");
printf(" \tfdupes documentation for additional information\n");
printf(" -r --recurse \tfor every directory given follow subdirectories\n");
printf(" \tencountered within\n");
printf(" -R --recurse: \tfor each directory given after this option follow\n");
printf(" \tsubdirectories encountered within (note the ':' at\n");
printf(" \tthe end of the option, manpage for more details)\n");
printf(" -s --symlinks \tfollow symlinks\n");
printf(" -H --hardlinks \tnormally, when two or more files point to the same\n");
printf(" \tdisk area they are treated as non-duplicates; this\n");
printf(" \toption will change this behavior\n");
printf(" -G --minsize=SIZE \tconsider only files greater than or equal to SIZE\n");
printf(" -L --maxsize=SIZE \tconsider only files less than or equal to SIZE\n");
printf(" -n --noempty \texclude zero-length files from consideration\n");
printf(" -A --nohidden \texclude hidden files from consideration\n");
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(" -t --time \tshow modification time of duplicate files\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");
printf(" \tothers; important: under particular circumstances,\n");
printf(" \tdata may be lost when using this option together\n");
printf(" \twith -s or --symlinks, or when specifying a\n");
printf(" \tparticular directory more than once; refer to the\n");
printf(" \tfdupes documentation for additional information\n");
#ifndef NO_NCURSES
printf(" -P --plain \twith --delete, use line-based prompt (as with older\n");
printf(" \tversions of fdupes) instead of screen-mode interface\n");
printf(" -P --plain \twith --delete, use line-based prompt (as with older\n");
printf(" \tversions of fdupes) instead of screen-mode interface\n");
#endif
printf(" -N --noprompt \ttogether with --delete, preserve the first file in\n");
printf(" \teach set of duplicates and delete the rest without\n");
printf(" \tprompting the user\n");
printf(" -I --immediate \tdelete duplicates as they are encountered, without\n");
printf(" \tgrouping into sets; implies --noprompt\n");
printf(" -p --permissions \tdon't consider files with different owner/group or\n");
printf(" \tpermission bits as duplicates\n");
printf(" -o --order=BY \tselect sort order for output and deleting; by file\n");
printf(" \tmodification time (BY='time'; default), status\n");
printf(" \tchange time (BY='ctime'), or filename (BY='name')\n");
printf(" -i --reverse \treverse order while sorting\n");
printf(" -l --log=LOGFILE \tlog file deletion choices to LOGFILE\n");
printf(" -v --version \tdisplay fdupes version\n");
printf(" -h --help \tdisplay this help message\n\n");
printf(" -N --noprompt \ttogether with --delete, preserve the first file in\n");
printf(" \teach set of duplicates and delete the rest without\n");
printf(" \tprompting the user\n");
printf(" -I --immediate \tdelete duplicates as they are encountered, without\n");
printf(" \tgrouping into sets; implies --noprompt\n");
printf(" -e --prefer=STRING\tprefer to keep a file which full pathname\n");
printf(" \tcontains STRING\n");
printf(" -p --permissions \tdon't consider files with different owner/group or\n");
printf(" \tpermission bits as duplicates\n");
printf(" -o --order=BY \tselect sort order for output and deleting; by file\n");
printf(" \tmodification time (BY='time'; default), status\n");
printf(" \tchange time (BY='ctime'), or filename (BY='name')\n");
printf(" -i --reverse \treverse order while sorting\n");
printf(" -l --log=LOGFILE \tlog file deletion choices to LOGFILE\n");
printf(" -v --version \tdisplay fdupes version\n");
printf(" -h --help \tdisplay this help message\n\n");
#ifndef HAVE_GETOPT_H
printf("Note: Long options are not supported in this fdupes build.\n\n");
#endif
Expand Down Expand Up @@ -1302,6 +1320,7 @@ int main(int argc, char **argv) {
{ "order", 1, 0, 'o' },
{ "reverse", 0, 0, 'i' },
{ "log", 1, 0, 'l' },
{ "prefer", 1, 0, 'e' },
{ 0, 0, 0, 0 }
};
#define GETOPT getopt_long
Expand All @@ -1315,7 +1334,7 @@ int main(int argc, char **argv) {

oldargv = cloneargs(argc, argv);

while ((opt = GETOPT(argc, argv, "frRq1StsHG:L:nAdPvhNImpo:il:"
while ((opt = GETOPT(argc, argv, "frRq1StsHG:L:nAdPvhNImpo:il:e:"
#ifdef HAVE_GETOPT_H
, long_options, NULL
#endif
Expand Down Expand Up @@ -1409,6 +1428,10 @@ int main(int argc, char **argv) {
case 'i':
SETFLAG(flags, F_REVERSE);
break;
case 'e':
SETFLAG(flags, F_PREFER);
preserved_word = optarg;
break;
case 'l':
loginfo = log_open(logfile=optarg, &log_error);
if (loginfo == 0)
Expand Down
3 changes: 2 additions & 1 deletion flags.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@
#define F_IMMEDIATE 0x8000
#define F_PLAINPROMPT 0x10000
#define F_SHOWTIME 0x20000
#define F_PREFER 0x40000

extern unsigned long flags;

#endif
#endif