Added the -f, --result-prefix option.
authorFrancois Fleuret <francois@fleuret.org>
Sun, 6 Mar 2011 10:17:43 +0000 (11:17 +0100)
committerFrancois Fleuret <francois@fleuret.org>
Sun, 6 Mar 2011 10:17:43 +0000 (11:17 +0100)
finddup.1
finddup.c

index 8a284ec..d6da915 100644 (file)
--- a/finddup.1
+++ b/finddup.1
@@ -72,6 +72,11 @@ files with same inode are considered as different
 \fB-e \fI<command>\fR, \fB--exec \fI<command>\fR
 execute the provided command for each group of identical files, with
 their names as arguments
+.TP
+\fB-f \fI<string>\fR, \fB--result-prefix \fI<string>\fR
+for each group of identical files, write one result file whose name is
+the given prefix string followed the group number, and containing one
+file name per line
 
 .SH "BUGS"
 
index 7dc2aba..bbb56d0 100644 (file)
--- a/finddup.c
+++ b/finddup.c
@@ -23,7 +23,7 @@
  *
  */
 
-#define VERSION_NUMBER "1.1"
+#define VERSION_NUMBER "1.2"
 
 #define _BSD_SOURCE
 
@@ -78,6 +78,8 @@ int sort_by_time = 0; /* 1 means to sort files in each group according
 char *command_to_exec = 0; /* the name of the command to exec for each
                               group of identical files */
 
+char *result_file_prefix = 0; /* The prefix to use to write result */
+
 /********************************************************************/
 
 /* malloc with error checking.  */
@@ -271,14 +273,14 @@ struct file_node *scan_directory(struct file_node *tail, const char *name) {
   return result;
 }
 
-void print_file(struct file_node *node) {
+void print_file(FILE *out, struct file_node *node) {
   char tmp[PATH_MAX + 1];
   if(show_realpaths) {
     if(realpath(node->name, tmp)) {
       if(show_groups) {
-        printf("%d %s\n", node->group_id, tmp);
+        fprintf(out, "%d %s\n", node->group_id, tmp);
       } else {
-        printf("%s\n", tmp);
+        fprintf(out, "%s\n", tmp);
       }
     } else {
       fprintf(stderr,
@@ -289,9 +291,9 @@ void print_file(struct file_node *node) {
     }
   } else {
     if(show_groups) {
-      printf("%d %s\n", node->group_id, node->name);
+      fprintf(out, "%d %s\n", node->group_id, node->name);
     } else {
-      printf("%s\n", node->name);
+      fprintf(out, "%s\n", node->name);
     }
   }
 }
@@ -371,6 +373,25 @@ void exec_command(int nb, struct file_node **nodes) {
   free(args);
 }
 
+void write_groups_in_files(int nb, struct file_node **nodes) {
+  FILE *file = 0;
+  int current_group = -1, n;
+  char filename[PATH_MAX + 1];
+
+  for(n = 0; n < nb; n++) {
+    if(nodes[n]->group_id != current_group) {
+      if(file) { fclose(file); }
+      sprintf(filename, "%s%06d", result_file_prefix, nodes[n]->group_id);
+      file = fopen(filename, "w");
+      current_group = nodes[n]->group_id;
+      printf("Writing %s.\n" , filename);
+    }
+    print_file(file, nodes[n]);
+  }
+
+  if(file) { fclose(file); }
+}
+
 void print_result(struct file_node *list1, struct file_node *list2) {
   struct file_node *node1, *node2;
   struct file_node **nodes;
@@ -408,12 +429,14 @@ void print_result(struct file_node *list1, struct file_node *list2) {
 
   if(command_to_exec) {
     exec_command(nb, nodes);
+  } else if(result_file_prefix) {
+    write_groups_in_files(nb, nodes);
   } else {
     for(n = 0; n < nb; n++) {
       if(!show_groups && n > 0 && nodes[n]->group_id != nodes[n-1]->group_id) {
         printf("\n");
       }
-      print_file(nodes[n]);
+      print_file(stdout, nodes[n]);
     }
   }
 
@@ -598,6 +621,11 @@ void usage(FILE *out) {
   fprintf(out, "   -e <command>, --exec <command>\n");
   fprintf(out, "                              execute the provided command for each group of\n");
   fprintf(out, "                              identical files, with their names as arguments\n");
+  fprintf(out, "   -f <string>, --result-prefix <string>\n");
+  fprintf(out, "                              for each group of identical files, write one\n");
+  fprintf(out, "                              result file whose name is the given prefix string\n");
+  fprintf(out, "                              followed the group number, and containing one\n");
+  fprintf(out, "                              filename per line\n");
   fprintf(out, "\n");
   fprintf(out, "Report bugs and comments to <francois@fleuret.org>.\n");
 }
@@ -616,6 +644,7 @@ static struct option long_options[] = {
   { "ignore-empty", no_argument, 0, '0' },
   { "show-progress", no_argument, 0, 'p' },
   { "exec", 1, 0, 'e' },
+  { "result-prefix", 1, 0, 'f' },
   { 0, 0, 0, 0 }
 };
 
@@ -624,7 +653,7 @@ int main(int argc, char **argv) {
 
   setlocale (LC_ALL, "");
 
-  while ((c = getopt_long(argc, argv, "vhircgtd0pme:",
+  while ((c = getopt_long(argc, argv, "vhircgtd0pme:f:",
                           long_options, NULL)) != -1) {
     switch (c) {
 
@@ -678,6 +707,14 @@ int main(int argc, char **argv) {
       command_to_exec = strdup(optarg);
       break;
 
+    case 'f':
+      if(result_file_prefix != 0) {
+        free(result_file_prefix);
+      }
+      result_file_prefix = strdup(optarg);
+      show_groups = 0;
+      break;
+
     default:
       usage(stderr);
       exit(EXIT_FAILURE);