Home > OS >  Move files to folder by date in a bash script
Move files to folder by date in a bash script

Time:06-07

I have few files named as per year month date format.

Example:

20220101 20220102 20220103 20220104 .. 20220130 20220131

As the file generated daily, I need to move 1st 2(20220101,20220102) and last 2(20220130,20220131) files in a specific folder every month. Can someone help me out how can I write the script?

CodePudding user response:

This helped me a long back -

#!/bin/bash

DIR=/Users/limeworks/Downloads/target
target=$DIR
cd "$DIR"

for file in *; do
    # Top tear folder name
    year=$(stat -f "%Sm" -t "%Y" $file)
    # Secondary folder name
    subfolderName=$(stat -f "%Sm" -t "%d-%m-%Y" $file)

    if [ ! -d "$target/$year" ]; then
        mkdir "$target/$year"
        echo "starting new year: $year"
    fi
    if [ ! -d "$target/$year/$subfolderName" ]; then
        mkdir "$target/$year/$subfolderName"
        echo "starting new day & month folder: $subfolderName"
    fi
    echo "moving file $file"
    mv "$file" "$target/$year/$subfolderName"

done

CodePudding user response:

well if you want to do this in bash i would suggest having a single script file and one log file to keep track of the current month/previous month.

#!/bin/bash
x=$(date  %D | cut -c 4,5 | sed 's|0||g')
y=$(sed -n 1p date.log 2>/dev/null) 
if ! [ -d date.log ]; then
  printf "$x" > date.log
  exit 0
fi
if [[ $y -ge 0 && $y -le 12 && $x != $y ]]; then
  #if the current month equal the previous month then everthing here will be exicuted
  echo "a new month is here"
else
  sed -i "1s/^.*$/$x/" date.log
fi  

what this script essentially dose is that it creates log file containing the current month "if it doesn't already exist and". After that "if executed again" it matches the new month value to the one contained in the log file if it doesn't match it executes everything where the commented text is which is most likely a bunch of mv commands.

CodePudding user response:

Try this Shellcheck-clean code:

#! /bin/bash -p

datefiles=( 20[0-9][0-9][01][0-9][0-3][0-9] )
mv -n -v -- "${datefiles[@]:0:2}" "${datefiles[@]: -2}" /path/to/folder
  • datefiles=( 20[0-9][0-9][01][0-9][0-3][0-9] ) makes an array of the files in the current directory with date-formatted names, sorted by name.
  • "${datefiles[@]:0:2}" expands to the first two elements in the datefiles array.
  • "${datefiles[@]: -2}" expands to the last two elements in the datefiles array.
  • You'll need to change /path/to/folder.
  • Unless it is absolutely guaranteed that there will always be at least 4 date files, you should add a check on the number of files found (eg. if (( ${#datefiles[*]} >= 4 )) ...).

CodePudding user response:

$ string="20220101 20220102 20220103 20220104 .. 20220130 20220131" 
$ awk '{ print |"mv " $1" "$2" "$(NF-1)" "$NF " /your/folder"}' <<<"$string"

or

$ myArray=(20220101 20220102 20220103 20220104 .. 20220130 20220131)
$ mv ${myArray[0]} ${myArray[1]} ${myArray[-2]} ${myArray[-1]} /your/folder

Files to array

$ myArray=($(find /path/to/files -mindepth 1 -maxdepth 1 -type f -name "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]" -print0))

or

$ readarray myArray < <(find /path/to/files -mindepth 1 -maxdepth 1 -type f -name "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]")
  • Related