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