'Flatten all the files into one folder and remove the keep only one of the file with the same name

Hi everyone I am working on this task where I have to flatten all files in the current directory, as well as all other files in any subdirectories inside it, into a single level. And then zipped the file and also removed the file with the same name. I try to search on the internet but could not find anything to start I hope you guys can help me with this one. Thanks in advance.

For example : Directory a1 has 5 files and 1 directory

|- a1
| |- j1.jpg
| |-j2.jpg
|- j2.jpg
|- j3.jpg
|- README

Input: > ./one.sh ./handin.zip

Expected Output It will create a file called handin.zip with j1.jpg j2.jpg j3.jpg README all together when unzipped.



Solution 1:[1]

The zip command has the -j option for storing files without their path. Unfortunately, it will fail when there is a duplicate name, so you need to preprocess the file list for eliminating the dups.

If you don't have any newline in the paths then you can do:

filelist=$(
    find . -type f |              # list all the files in the current directory
    sed -E 's,(.*/(.*)),\2/\1,' | # prepend the filename at the start of the path
    sort -u -t / -k 1,1 |         # remove duplicate filenames
    sed 's,[^/]*/,,'              # strip the filename from the start of the path
)
echo "$filelist" | zip -j handin.zip -@

Solution 2:[2]

Using zip -j to junk the paths and awk to remove duplicate filenames

-j --junk-paths Store just the name of a saved file (junk the path) , and do not store directory names. By default, zip will store the full path (relative to the current directory).

a[$NF]=$0 stores filename => path/to/file into array (overwrites duplicates)

END{for(i in a)print a[i]} output filelist from array

zip -j handin.zip -@ zip filelist from stdin (junk the paths)

find . -type f|awk -F/ '{a[$NF]=$0}END{for(i in a)print a[i]}'| zip -j handin.zip -@

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2