Elderwyrm
Elderwyrm

Reputation: 109

Is there a better way to swap the first half and the last half of a file's name in BASH?

So, I wrote some a BASH shell script for renaming image files downloaded from deviant art so the artist name comes first, then the name of the piece of art. (for those not familiar with dA, the system names downloadable image files as imageTitle_by_ArtistsName.extention, which makes it hard to organize images quickly). It works... but it seems so clunky. Is there a more elegant way to handle this?

The code:

#!/bin/bash
#############################
# A short script for renaming
#Deviant Art files
#############################

echo "Please enter your image directory: "
read NewDir

echo "Please enter your destination directory: "
read DestinationDir

mkdir $DestinationDir
cd $NewDir


ls>>NamePile

ListOfFiles=`cat NamePile`


for x in $ListOfFiles
do


#Pull in the file Names
FileNameVar=$x


#Get the file types
FileType='.'${FileNameVar#*.}

#Chop the Artists name
ArtistsName=${FileNameVar%%.*}
ArtistsName=${ArtistsName##*_by_}

#Chop the pieces name
ImageName=${FileNameVar%%.*}
ImageName=${ImageName%%_by_*}

#Reassemble the New Name
NewFileName=$ArtistsName" "$ImageName$FileType

cp $x ../$DestinationDir/"$NewFileName"


done

rm NamePile
#######################################

Upvotes: 1

Views: 120

Answers (2)

chepner
chepner

Reputation: 531325

You can simply the loop greatly by using regular expression matching.

for file in *; do  # Don't parse the output of ls; use pattern matching
  [[ $file =~ (.*)_by_(.*)\.(.*) ]] || continue

  imageName="${BASH_REMATCH[1]}"
  artistsName="${BASH_REMATCH[2]}"
  fileType="${BASH_REMATCH[3]}"

  cp "$file" "../$DestinationDir/$artistsName $imageName.$fileType"
done

Upvotes: 3

Mansoor Siddiqui
Mansoor Siddiqui

Reputation: 21663

When writing shell scripts, it's usually easiest to simply make use of existing Linux utilities. In this case, for example, sed can do most of the heavy lifting for you. This probably isn't the most robust code snippet, but you get the idea:

for file in *.jpg; do
    newFile=`echo $file | sed 's/\(.*\)_by_\(.*\)\(\..*\)/\2_\1\3/g'`
    mv $file $newFile
done

Upvotes: 1

Related Questions