Did I just delete everything with find -exec mv?
I tried to figure this out on my own. Here's the command I used in the terminal:
find . -name "*.jpg" -exec mv {} pictures \;
I did not create a directory named pictures first. What happened was a file named pictures.gif was created. Did it find the files then overwrite them as it moved them?
What is this pictures.gif file that has been created as a result of this command?
Are the files still possibly on the drive somewhere?
Solution 1:
First: stop using this drive now. It's ok to remount it read-only, just make sure not to do any more writing. Yes, you've deleted the pictures. They may be recoverable, but the more you keep using that drive, the less chance you have to recover anything.
Your command ran mv pic1.jpg pictures
, mv pic2.jpg pictures
, etc. Each invocation of mv
overwrote the file currently named pictures
by another picture.
Moving a file (within the same filesystem) means detaching it from the directory that contains it and attaching it to the target directory under the new name. So no file data was modified or deleted by this command, only the directory entries for the images that have disappeared.
You can run a tool that scours your filesystem's free space and looks for things that look like jpegs. Fortunately, every jpeg file starts with a recognizable header. Tools that look for deleted content are called carving tools. There are a few in Ubuntu, including recoverjpeg, foremost, testdisk, … If the photos are on a separate home partition or on an external drive, install one or more of those packages and point them to the partition with the deleted pictures.
If the photos are on your system disk, you need to stop using your system immediately. Use another computer to download a live CD or USB and boot from that. Any of the live CDs that include testdisk should fit the bill, but some are easier to use than others. System Rescue CD is a good general-purpose system rescue CD. Ubuntu Rescue Remix may be more familiar for an Ubuntu user.
For future reference, get into the habit of using mv -i
unless you aim to overwrite files. You may already have an alias for mv
, but that only kicks in when you type mv
directly on the command line, not when mv
is invoked by a script or by the find
command.
$ : >pictures
$ mv -i foo.jpg pictures
mv: overwrite `pictures'?
Also, if you put a /
after a name that is supposed to be the name of a directory, you'll get an error if the directory doesn't exist, or if there is a file by that name which isn't a directory.
$ : >pictures
$ mv foo.jpg pictures/
mv: cannot move `foo.jpg' to `pictures/': Not a directory
$ rm pictures
$ mv foo.jpg pictures/
mv: cannot move `foo.jpg' to `pictures/': Not a directory
To avoid the pitfalls of find
, you could use bash's recursive directory traversal feature instead. You need to turn it on first with the command shopt -s globstar
(you can add this line to your ~/.bashrc
. Then:
mv **/*.jpg pictures/
(Note that in bash, **/
also traverses symbolic links to directories, and there's no way to turn this off. If you want a recursive traversal that doesn't look through symbolic links to directories, use zsh or find.)
Solution 2:
I am afraid that you have just lost all your pictures into that single file. It is possible to recover some files using forensic tools like foremost, but the success rate drops the longer you use the media (disk). (to be precise, the longer the partition is mounted.)
Next time, when you mean a directory, add a slash to it and add the -i
option to ask for confirmation in case a file already exists:
find -name "*.jpg" -exec mv -i {} pictures/ {} \;