#@begin_function flatten
function flatten() {
local -a flatten
local -a duplicates
local current_dir
current_dir=$(pwd)
readarray -t flatten < <(find "$current_dir" -type f)
if [ "${#flatten[@]}" -eq 0 ]; then
printf "No files found in subdirectories.\n" >&2
return 1
else
printf "%s\n" "${flatten[@]}"
printf "\nFound %s files in %s subdirectories.\n" "${#flatten[@]}" "$(find "$current_dir" -type d | wc -l)"
fi
read -rp "This will move all files in subdirectories to the current directory. Continue? (Y\N) : " answer
if [[ ! $answer =~ ^[Yy] ]]; then
printf "Aborting...\n" >&2
return 1
fi
for ((i = 0; i < "${#flatten[@]}"; i++)); do
if ! mv --no-clobber --verbose "${flatten[$i]}" "$current_dir" 2>/dev/null; then
duplicates+=("${flatten[$i]}")
fi
done
if [ "${#duplicates[@]}" -gt 0 ]; then
printf "\nThe following files were not moved due to duplicates:\n"
printf "%s\n" "${duplicates[@]}"
fi
}
#@end_function
// flatten.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <unistd.h>
void flatten() {
char *current_dir = getcwd(NULL, 0);
if (current_dir == NULL) {
perror("getcwd");
return;
}
DIR *dir = opendir(current_dir);
if (dir == NULL) {
perror("opendir");
free(current_dir);
return;
}
struct dirent *entry;
int file_count = 0;
int dir_count = 0;
char **files = NULL;
size_t files_size = 0;
while ((entry = readdir(dir)) != NULL) {
if (entry->d_type == DT_DIR) {
dir_count++;
} else if (entry->d_type == DT_REG) {
files_size++;
files = realloc(files, files_size * sizeof(char *));
files[files_size - 1] = strdup(entry->d_name);
file_count++;
}
}
closedir(dir);
if (file_count == 0) {
fprintf(stderr, "No files found in subdirectories.\n");
free(current_dir);
return;
} else {
for (size_t i = 0; i < files_size; i++) {
printf("%s\n", files[i]);
}
printf("\nFound %d files in %d subdirectories.\n", file_count, dir_count);
}
char answer;
printf("This will move all files in subdirectories to the current directory. Continue? (Y/N) : ");
scanf(" %c", &answer);
if (answer != 'Y' && answer != 'y') {
fprintf(stderr, "Aborting...\n");
free(current_dir);
for (size_t i = 0; i < files_size; i++) {
free(files[i]);
}
free(files);
return;
}
for (size_t i = 0; i < files_size; i++) {
char new_path[PATH_MAX];
snprintf(new_path, sizeof(new_path), "%s/%s", current_dir, files[i]);
if (rename(files[i], new_path) != 0) {
perror("rename");
}
free(files[i]);
}
free(files);
free(current_dir);
}