N M
N M

Reputation: 616

File name change script not working in second run of loop

This code is meant to search a set of folders containing files with name format DD-MM-YYYY and renames them as YYYY-MM-DD. However, while this loop works fine on the first iteration, it doesn't interpret the regular expression in the second run.

#!/usr/bin/env bash
WORKING_DIRS=( "/directory1" "/directory2" )
for WORKING_DIR in ${WORKING_DIRS[@]}
do
echo "WORKING DIRECTORY : $WORKING_DIR"
echo "--------------------------------------------------------"
for entry in "$WORKING_DIR"/[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9].doc
do
    IFS='/'
    read -r -a array <<< "$entry"
    file_name="${array[${#array[@]}-1]}"
    echo "$file_name"
    IFS='.'
    read -r -a file <<< "$file_name"
    echo "OLD DATE: $file"
    IFS='-'
    read -r -a file_split <<< "${file[0]}"
    day=${file_split[0]}
    month=${file_split[1]}
    year=${file_split[2]}
    new_date="$year-$month-$day"
    echo "NEW DATE : $new_date"
    mv "$WORKING_DIR"/"$file_name" "$WORKING_DIR"/"$new_date".doc
done
done

Upvotes: 1

Views: 53

Answers (2)

Inian
Inian

Reputation: 85550

The problem is with the IFS value modification in the body of the loop multiple times. Once you modify it the rest of the word-splitting is done by the modified IFS which does not allow your glob pattern to expand.

You can avoid it by passing the value to the read command locally and not modifying it globally, which should solve your problem.

IFS='/' read -r -a array <<< "$entry"
IFS='.' read -r -a file <<< "$file_name"
IFS='-' read -r -a file_split <<< "${file[0]}"

Also in general in looping over a glob pattern it is always to check the file existence before processing the file, to avoid ugly errors

for entry in "$WORKING_DIR"/[0-9][0-9]-[0-9][0-9]-[0-9][0-9][0-9][0-9].doc
do
    [ -e "$entry" ] || continue

    # rest of the code following 

(and)

Double-quoting the array expansion as below to avoid getting the individual elements split again. Not doing so, will result in each entry of the array subject to word-splitting by IFS

for WORKING_DIR in "${WORKING_DIRS[@]}"; do

Upvotes: 1

Renaud Pacalet
Renaud Pacalet

Reputation: 28965

Not sure why your script does not work but without an example content of your directories, it is difficult to reproduce the error. Anyway, it looks a bit complicated for a rather simple task. You could simplify, e.g. by using the =~ operator of the conditional expressions. Example:

for n in "$WORKING_DIR"/*.doc; do
  if [[ $n =~ (.*\/)([0-9][0-9])(-[0-9][0-9]-)([0-9][0-9][0-9][0-9])\.doc ]]; then
    mv $n ${BASH_REMATCH[1]}${BASH_REMATCH[4]}${BASH_REMATCH[3]}${BASH_REMATCH[2]}.doc
  fi
done

Upvotes: 0

Related Questions