The Situation:
I have hundreds of zip files with an arbitrary date/time mixed into its name (4-6-2021 12-34-09 AM.zip
). I need to get all of these files in order such that (0.zip, 1.zip 2.zip etc) with in a Linux cli system.
What I’ve tried:
I’ve tried ls -tr | while read i; do n=$((n+1)); mv -- "$i" "$(printf '%03d' "$n").zip"; done
which almost does what I want but still seems to be out of order (I think its taking the order of when the file was created rather than the filename (which is what I need)).
If I can get this done, my next step would be to rename the file (yes a single file) in each zip to the name of the zip file. I’m not sure how I’d go about this either.
tl;dr
I have these files named with a weird date system. I need the date to be in order and renamed sequentially like 0.zip 1.zip 2.zip etc
. It’s 3:00 AM and I don’t know why I’m up still trying to solve this and I have no idea how I’ll rename the files in the zips to that sequential number (read above for more detail on this).
Thanks in advance!
Advertisement
Answer
GNU awk is an option here, redirecting the result of the file listing back into awk:
awk '{ fil=$0; # Set a variable fil to the line gsub("-"," ",$1); # Replace "-" for " " in the first space delimited field split($1,map," "); # Split the first field into the array map, using " " as the delimiter if (length(map[1])==1) { map[1]="0"map[1] # If the length of the day is 1, pad out with "0" }; if (length(map[2])==1) { map[2]="0"map[2] # Do the same for month } $1=map[1]" "map[2]" "map[3]; # Rebuilt first field based on array values gsub("-"," ",$2); # Change "-" for " " in time map1[mktime($1" "$2)]=fil # Get epoch format of date/time using mktime function and use this as an index for array map1 with the original line (fil) as the value } END { PROCINFO["sorted_in"]="@ind_num_asc"; # At the end of processing, set the array sorting to index number ascending cnt=0; # Initialise a cnt variable for (i in map1) { print "mv ""map1[i]"" ""cnt".zip""; # Loop through map1 array printing values and using these values along with cnt to generate and print move command cnt++ } }' <(for fil in *AM.zip;do echo $fil;done)
Once you are happy with the way the print command are printed, pipe the result into bash and so:
awk '{ fil=$0;gsub("-"," ",$1);split($1,map," ");if (length(map[1])==1) { map[1]="0"map[1] };if (length(map[2])==1) { map[2]="0"map[2] }$1=map[1]" "map[2]" "map[3];gsub("-"," ",$2);map1[mktime($1" "$2)]=fil} END { PROCINFO["sorted_in"]="@ind_num_asc";cnt=0;for (i in map1) { print "mv ""map1[i]"" ""cnt".zip"";cnt++ } }' <(for fil in *AM.zip;do echo $fil;done) | bash