user1054844
user1054844

Reputation: 972

How do I manipulate filenames in bash?

I have a bunch of images that I need to rename, so I can use them and I was wondering how to do this.

The way they need to be is that first 5 will be kept and then for the 6th I would write a number from 1-3. I only know that the first 5 are static; on pics belonging to same "family" and can be used for comparison and the 6th char is not known.

Example:

12345random.jpg

12345randomer.jpg

0987654more_random.jpg

09876awesome.jpg

09876awesomer.jpg

09876awesomest.jpg

09876soawesomegalaxiesexplode.jpg

would become.

12345.jpg

123452.jpg

09876.jpg

098761.jpg

098762.jpg

It would be cool if it would only handle the loop so that 3 pics could be only renamed and rest skipped.

I found some stuff on removing letters to certain point, but nothing that use, since I am quite poor at bash scripting.

Here is my approach, but it kind of sucks, since I tried modifying scripts I found, but the idea is there

//I could not figure how to remove the chars after 5th not the other way around
for file in .....*; do echo mv $file `echo $file | cut -c6-`; done
   
done
//problem also is that once the names conflict it produces only 1 file named 12345.jpg 2nd one will not be created
    //do not know how to read file names to array
    name=somefile
    if [[ -e $name.jpg]] ; then
        i=0
        while [[ -e $name-$i.jpg]] ; do
            let i++
        done
        name=$name-$i
    fi
    touch $name.jpg

Upvotes: 1

Views: 69

Answers (2)

shiv garg
shiv garg

Reputation: 791

you can also try the following code but be careful all the files should be in .jpg format and pass the name of folder as an argument

#!/bin/bash
a=`ls $1`
for b in $a
do
echo $b
if (( i<4 ))
then 
c=`echo $b | cut -c1-5`
let i=i+1
c="$c$i.jpg"
echo $c
else
c=`echo $b | cut -c1-5` 
c="$c.jpg"
break
fi
mv $1$b $1$c
done

Upvotes: 1

konsolebox
konsolebox

Reputation: 75458

You can have:

new_file=${file%%[^0-9]*.jpg}.jpg

As a concept you can have this to rename files:

for file in *.jpg; do
    [[ $file == [0-9]*[^0-9]*.jpg ]] || continue  ## Just a simple check.
    new_file=${file%%[^0-9]*.jpg}.jpg
    [[ -e $new_file ]] || continue  ## Do not overwrite. Delete line if not wanted.
    echo "Renaming $file to $new_file."  ## Optional message.
    mv -- "$file" "$new_file" || echo "Failed to rename $file to $new_file."
done

If you're going to process files that also contain directory names, you'll need some more changes:

for file in /path/to/other/dirs/*.jpg *.jpg; do
    base=${file##*/}
    [[ $base == [0-9]*[^0-9]*.jpg ]] || continue
    if [[ $file == */* ]]; then
        new_file=${file%/*}/${base%%[^0-9]*.jpg}.jpg
    else
        new_file=${file%%[^0-9]*.jpg}.jpg
    fi
    [[ -e $new_file ]] || continue
    echo "Renaming $file to $new_file."
    mv -- "$file" "$new_file"
done

Upvotes: 3

Related Questions