Reputation: 4792
I have a large number of image files that i need to rename from the comand line. I believe the best way to do this is to use awk (please correct if this is incorrect).
file names are like the following
1038282829128738912-1.jpg
Every image file starts with '103' and I want to replace this part of the file name with '201003' - leaving the rest intact ... eg.
2010038282829128738912-1.jpg
The images are in multiple folders under one main folder (images) - but it would be handy for all the images to be copied into one folder (images_renamed)
I don't know where to start with this - and I have googled for awk usage but can only find examples of renaming text inside files.
Any help appreciated. Thanks/
Upvotes: 3
Views: 4407
Reputation: 61
haven't tested but something like this could work in bash:
for i in `ls 103*.jpg`; do cp $i newdir/201003${i:3}; done
Upvotes: -1
Reputation: 881563
If you have the rename
command on your UNIX, you should be able to use something like:
mkdir images_renamed
cd images_renamed
cp ../103*.jpg .
rename 103 201003 *.jpg
The rename FROM TO FILE
will rename all the files specified by FILE
, changing the first occurrence of FROM
to TO
.
If that's not available, you can use something like:
mkdir images_renamed
for fspec in 103*.jpg ; do
cp ${fspec} images_renamed/201003${fspec:3}
done
To do this recursively, I would put it into a script with find
:
#!/usr/bin/bash
rm -rf images_renamed
ls -lR images
echo
cd images
find . -name '*.jpg' | while read -r; do
mkdir -p "../images_renamed/$(dirname "$REPLY")"
echo 'Copying from' [$REPLY]
echo ' to' [../images_renamed/$REPLY] and renaming.
echo
cp "$REPLY" "../images_renamed/$REPLY"
cd "$(dirname "../images_renamed/$REPLY")"
rename 103 201003 "$(basename "$REPLY")"
cd - >/dev/null
done
cd ..
ls -lR images_renamed
Only the middle bit of that is required, the rest is for testing. The output below shows how it works, copying across every file to the new directory structure and renaming the relevant files.
images:
total 0
drwxr-xr-x+ 1 pax None 0 2010-08-12 20:55 dir1
drwxr-xr-x+ 1 pax None 0 2010-08-12 20:55 dir2
drwxr-xr-x+ 1 pax None 0 2010-08-12 20:56 dir3
images/dir1:
total 0
-rw-r--r-- 1 pax None 0 2010-08-12 20:55 102xxx.jpg
-rw-r--r-- 1 pax None 0 2010-08-12 20:55 103xxx.jpg
images/dir2:
total 0
-rw-r--r-- 1 pax None 0 2010-08-12 20:55 103yyy.jpg
images/dir3:
total 0
drwxr-xr-x+ 1 pax None 0 2010-08-12 20:55 dir 4
images/dir3/dir 4:
total 0
-rw-r--r-- 1 pax None 0 2010-08-12 20:55 103zzz.jpg
Copying from [./dir1/102xxx.jpg]
to [../images_renamed/./dir1/102xxx.jpg] and renaming.
Copying from [./dir1/103xxx.jpg]
to [../images_renamed/./dir1/103xxx.jpg] and renaming.
Copying from [./dir2/103yyy.jpg]
to [../images_renamed/./dir2/103yyy.jpg] and renaming.
Copying from [./dir3/dir 4/103zzz.jpg]
to [../images_renamed/./dir3/dir 4/103zzz.jpg] and renaming.
images_renamed:
total 0
drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir1
drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir2
drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir3
images_renamed/dir1:
total 0
-rw-r--r-- 1 pax None 0 2010-08-12 21:19 102xxx.jpg
-rw-r--r-- 1 pax None 0 2010-08-12 21:19 201003xxx.jpg
images_renamed/dir2:
total 0
-rw-r--r-- 1 pax None 0 2010-08-12 21:19 201003yyy.jpg
images_renamed/dir3:
total 0
drwxr-xr-x+ 1 pax None 0 2010-08-12 21:19 dir 4
images_renamed/dir3/dir 4:
total 0
-rw-r--r-- 1 pax None 0 2010-08-12 21:19 201003zzz.jpg
To flatten the file hierarchy, you can use something like:
#!/usr/bin/bash
rm -rf images_renamed
ls -lR images
echo
cd images
mkdir -p ../images_renamed
find . -name '*.jpg' | while read -r; do
newfile="$(basename "$REPLY")"
echo 'Copying from' [$REPLY]
echo ' to' [../images_renamed/$newfile] and renaming.
echo
cp "$REPLY" "../images_renamed/$newfile"
cd ../images_renamed
rename 103 201003 "$newfile"
cd - >/dev/null
done
which outputs:
cd ..
ls -lR images_renamed
images:
total 0
drwxr-xr-x+ 1 allan None 0 2010-08-12 20:55 dir1
drwxr-xr-x+ 1 allan None 0 2010-08-12 20:55 dir2
drwxr-xr-x+ 1 allan None 0 2010-08-12 20:56 dir3
images/dir1:
total 0
-rw-r--r-- 1 allan None 0 2010-08-12 20:55 102xxx.jpg
-rw-r--r-- 1 allan None 0 2010-08-12 20:55 103xxx.jpg
images/dir2:
total 0
-rw-r--r-- 1 allan None 0 2010-08-12 20:55 103yyy.jpg
images/dir3:
total 0
drwxr-xr-x+ 1 allan None 0 2010-08-12 20:55 dir 4
images/dir3/dir 4:
total 0
-rw-r--r-- 1 allan None 0 2010-08-12 20:55 103zzz.jpg
Copying from [./dir1/102xxx.jpg]
to [../images_renamed/102xxx.jpg] and renaming.
Copying from [./dir1/103xxx.jpg]
to [../images_renamed/103xxx.jpg] and renaming.
Copying from [./dir2/103yyy.jpg]
to [../images_renamed/103yyy.jpg] and renaming.
Copying from [./dir3/dir 4/103zzz.jpg]
to [../images_renamed/103zzz.jpg] and renaming.
images_renamed:
total 0
-rw-r--r-- 1 allan None 0 2010-08-12 22:41 102xxx.jpg
-rw-r--r-- 1 allan None 0 2010-08-12 22:41 201003xxx.jpg
-rw-r--r-- 1 allan None 0 2010-08-12 22:41 201003yyy.jpg
-rw-r--r-- 1 allan None 0 2010-08-12 22:41 201003zzz.jpg
but you need to keep in mind that filename clashes (the same file name under different directories) will overwrite each other.
Upvotes: 7
Reputation: 342423
find /path -type f -name "10*jpg" | sed 's/.*/mv &/' | sed 's/mv \(.*\/\)\(.[^/]*\)/& \120\2/' | sh
Upvotes: 0
Reputation: 274622
The following should work:
ls -d images*
images/ images_renamed/
for i in `find images -type f`
do
cp $i images_renamed/$(basename $i | sed s/^103/201003/)
done
Upvotes: 0
Reputation: 7281
Something like this could help:
cd images
find . -name '*.jpg' | while read -r img; do
mkdir -p "../images_renamed/$(dirname "$img")"
cp -v "$img" "../images_renamed/$(echo "$img" | sed -e 's/^103/201003/')"
done
Note: Not tested. Should not delete things though.
Upvotes: 0
Reputation: 15758
In ZSH you can do this (probably works in Bash too, not sure about this):
for f in **/103*.jpg; mv $f some_other_directory/201003${${f:t}#103}
Maybe I can also interest you in a tool I wrote: http://github.com/jkramer/virn It allows you to mass-rename files using Vim, including all of Vims features like regex etc. (Actually, you can use any other $EDITOR as well).
Upvotes: 0