2

So here's the deal, my girlfriend wants me to transfer all of her photos off from her iPhone onto her laptop (on which we are running Ubuntu 14.04). All of the dedicated programs I tried to do this with did not work, so I just copied the entire DCIM/ folder, which contains all of the pictures on her iPhone. My predicament is that DCIM/ is divided into four folders, which then contain an individual folder for each of her photos. In each of those folders, every picture has the same name, '5003.jpg'.

I want to move and rename (probably with ascending numerical names, e.g. 0001.jpg, 0002.jpg, etc.) all of these files to one folder, say ~/Pictures/iPhone/, using the command line.

So far all i've managed to do is compile a text file of all the individual paths for each file.

Some example path names:

/home/jennie/Pictures/DCIM/101APPLE/IMG_1703.JPG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1431.PNG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1933.JPG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1388.JPG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1954.JPG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1524.JPG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1897.PNG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1582.PNG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1007.PNG/5003.JPG
/home/jennie/Pictures/DCIM/101APPLE/IMG_1502.JPG/5003.JPG
2
  • Are you sure you've copied that path correctly? It has a directory named IMG_1002.JPG? Could you please paste in the output produced on the command line when you run find ~/Pictures/DCIM -type f -iname \*.jpg | head?
    – Wildcard
    Commented Jan 16, 2016 at 5:14
  • /home/jennie/Pictures/DCIM/101APPLE/IMG_1703.JPG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1431.PNG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1933.JPG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1388.JPG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1954.JPG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1524.JPG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1897.PNG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1582.PNG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1007.PNG/5003.JPG /home/jennie/Pictures/DCIM/101APPLE/IMG_1502.JPG/5003.JPG
    – user151768
    Commented Jan 16, 2016 at 7:01

4 Answers 4

3

Since you are flexible about the final file names, and these are photos from a modern smartphone, I recommend exiftool to automatically organize and rename photos for you:

  1. first, make a copy/back up your ~/Pictures/iPhone so you always have an something to fall back on if needed
  2. run the exiftool on your command prompt with these options:
$ exiftool -P -r '-FileName<DateTimeOriginal' -d ~/outdir/%Y-%m-%d/%H/%Y-%m-%d_%H.%M.%S.%%e ~/Pictures/iPhone

This should empty your ~/Pictures/iPhone, re-organizing and renaming them based on the EXIF timestamp data that the iPhone automatically embedded into each photo, into a newly generated ~/outdir directory. The resulting directory path and image file names will look something like this:

 ~/outdir/2016-01-03/10/2016-01-03_10.38.58.jpg

Installing

If you don't have exiftool, you can install with

$ sudo apt-get install libimage-exiftool-perl

Options

  • '-FileName<DateTimeOriginal' is literal, part of the argument
  • -d specifies destination template, you can change for example ~/outdir to another path of your choice
  • currently the %H/ part is what further creates a per hour sub-directory, within each date directory. If you prefer not to have such per-hour sub-directories, you can just omit the hour part, like this: ~/outdir/%Y-%m-%d/%Y-%m-%d_%H.%M.%S.%%e
  • or if you don't even want per-date directories, just want images directly in ~/outdir, you can omit the date directory part and just do: ~/outdir/%Y-%m-%d_%H.%M.%S.%%e
2

#!/bin/bash

appledir="$HOME/Pictures/DCIM/101APPLE"
jpgname="5003.JPG"

for   dir   in "$appledir"/*
do    if    [[ -d "$dir" ]]
      then
          newfile="$appledir/${dir##*/}"
          mv "$dir"/5003.JPG "$newfile.tmp" &&
          rmdir "$dir" &&
          mv "$newfile.tmp" "$newfile"
      fi
done

With an initial tree as this:

$ tree Pictures/
Pictures/
└── DCIM
    └── 101APPLE
        ├── IMG_1002.JPG
        │   └── 5003.JPG
        ├── IMG_1003.JPG
        │   └── 5003.JPG
        └── IMG_1004.JPG
            └── 5003.JPG

After executing the script (./script.sh), this will be the tree:

$ tree Pictures/
Pictures/
└── DCIM
    └── 101APPLE
        ├── IMG_1002.JPG
        ├── IMG_1003.JPG
        └── IMG_1004.JPG

Edit:

To rename *.PNG files back to *.JPG, use:

for     name   in "$HOME/Pictures/DCIM/101APPLE"/*.PNG
do      mv -i "$name" "${name%PNG}JPG"
done
8
  • nice answer. its readable and if it didn;t work at first , you could edit as needed. If I was going to use it, I would probably stat the files and possibly use a time stamp from the modified time as the file name. as long as you used an ISO style format it would still sort the same Commented Jan 16, 2016 at 4:58
  • @the_velour_fog I didn't want to make the script so complex, but it is easy to change the newfile= to any time stamp, if that is required.
    – user79743
    Commented Jan 16, 2016 at 6:16
  • Thank you very much! Your script worked, but there's one problem; some of the directories are named with .PNG as the suffix, although all contain .JPG files, so now I have a bunch of .JPGs named as .PNGs
    – user151768
    Commented Jan 16, 2016 at 7:31
  • @user151768: for file in *.PNG ; do mv -n "$file" "${file%.PNG}.JPG" ; done
    – Wildcard
    Commented Jan 16, 2016 at 7:34
  • I used a -n switch, though, so no damage would be done. That's a safeguard I advise keeping regardless of what directory you do it in.
    – Wildcard
    Commented Jan 16, 2016 at 7:57
1

You can use it all in one line:

find -name '*.JPG' | awk 'BEGIN{ i=1 }{ printf "mv \"%s\" %04d.jpg\n", $0, i++ }'| bash 

Use it from /Pictures folder for example. You search for all the JPG files, after that, the awk pipe gets the source and increases it in a 4 digit counter. We send to bash this pipe

3
  • There are hundred files. I believe you really should use xargs for your solution (twice).
    – appomsk
    Commented Jan 16, 2016 at 5:38
  • You answer gives the error awk: 1: unexpected character '\'
    – user151768
    Commented Jan 16, 2016 at 7:08
  • Corrected \"%s\" This was to avoid strange behaviors on names of files like "rm -rf" but i scaped the " character in a wrong way Commented Jan 16, 2016 at 9:39
0

For example having this

cat list-of-files
path1/file1
path2/file1

we can do that. Better reset a variable every time:

a=0; cat list-of-files |  while read -r f; do
  echo mv -v "$f" $((++a)).jpg
done 
mv -v path1/file1 1.jpg
mv -v path2/file1 2.jpg

Echo for checking. Delete it for actual removing.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .