Skip to content
Advertisement

Renaming Sequentially Named Files with Date Embedded

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
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement