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

Time:05-09

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.

CodePudding user response:

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 -@

CodePudding user response:

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 -@
  • Related