AndreasInfo
AndreasInfo

Reputation: 1227

Sort files in a directory before renaming them

I am learning Bash and therefore I would like to write a script with runs over my files and names them after the current directory.

E.g. current_folder_1, current_folder_2, current_folder_3...

#!/bin/bash

# script to rename images, sorted by "type" and "date modified" and named by current folder

#get current folder which is also basename of files
basename=$(basename "$PWD");
echo "Current folder is: ${basename}";
echo '';

#set counter for iteration and variables
counter=1;
new_name="";
file_extension="";

#for each file in current folder
for f in *
do
  #catch file name
  echo "Current file is:           ${f}"
  #catch file extension
  file_extension="${f##*.}";
  echo "Current file extension is: ${file_extension}"
  #create new name
  new_name="${basename}_${counter}.${file_extension}"
  echo "New name is:               ${new_name}";


  #mv $f "${new_name}";
  echo "Counter is:                ${counter}"
  ((counter++));
done

One of my two problems is I would like to sort them by first type and then date_modified before running the for-each-loop.

enter image description here

Something like

for f in * | sort -k "type" -k "date_modified"
[...]

I'd appreciate some help.

EDIT1: Solved the sorting by date problem with

for f in $(ls -1 -t -r)

Upvotes: 1

Views: 133

Answers (3)

Shaqil Ismail
Shaqil Ismail

Reputation: 1961

ls -lt | sort

The -t parameter will sort by date and time, and sort should sort by type of file.

Upvotes: 0

AndreasInfo
AndreasInfo

Reputation: 1227

I decided to do a workaround with two loops, one for images and one for video.

#used for regex
shopt -s extglob

#used to get blanks in filenames
SAVEIFS=$IFS;
IFS=$(echo -en "\n\b");
[...]

image_extensions="(*.JPG|*.jpg|*.PNG|*.png|*.JPEG|*.jpeg)"
video_extensions="(*.mp4|*.gif)"
[...]
for f in $(ls -1 -t -r *${media_file_extensions})
[...]
for f in $(ls -1 -t -r *${video_extensions})
[...]

#reverse IFS to default
IFS=$SAVEIFS;

Upvotes: 0

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

This could be a start. I've commented in the code where I think it's needed but please ask if anything is unclear.

#!/bin/bash

#get current folder which is also basename of files
folder=$(basename "$PWD");
echo "Current folder is: ${folder}";
echo

#set counter for iteration
counter=1;

for f in *
do
    file_extension="${f##*.}";

    # replace all whitespaces with underscores
    sort_extension=${file_extension//[[:space:]]/_}

    # get modification time in seconds since epoch
    sort_modtime=$(stat --format=%Y "$f")

    # output fed to sort
    echo $sort_extension $sort_modtime "/$f/"

    # sort on extension first and modification time after
done | sort -k1 -k2n | while read -r dummy1 dummy2 file
do
    # remove the slashes we added above
    file=${file:1:-1}

    file_extension="${file##*.}";

    new_name="${folder}_${counter}.${file_extension}"

    echo "moving \"$file\" to \"$new_name\""
    #mv "$file" "$new_name"

    (( counter++ ))
done

Upvotes: 1

Related Questions