Find and move filles with specific extensions

dimzev

New Member
From a specific file I want find all images(JPG,jpg,png,...) and move (not copy) all this images to a new folder

Please give me the command in terminal
If I want copy from this images in a usb how above command change?

Please give me a help
 


Tolkem

Member
Hi @dimzev We need more info like what folder you're trying to move file from, distro; Ubuntu, Arch, Debian, SUSE, Slack, BSD, what do you mean by "from a specific file"? That info is relevant cause depending on it answers may vary. Please, elaborate a bit more so we can offer some help :)
 

atanere

Well-Known Member
Hi @dimzev, and welcome! Your best answer will probably come from @JasKinasis when he pops in, but I'll start off by separating your first request.... how to find. There will be many different ways to solve your problem, and I just stumble along with the command line, so my methods are not likely to be the best way.

From a specific file I want find all images(JPG,jpg,png,...)
This is a little confusing. I guess that you mean "from a specific folder (or location)" because the image files won't be stored in another file, unless it is a zip file, tar file, or some other type of archive. But you did not give us a specific folder or location, so we might only substitute some examples, like these:

Code:
find / -name '*.jpg'
find /home -name '*.jpg'
find /home/dimzev -name '*.jpg'
find . -name '*.jpg'
This would find all .jpg files in 1. your whole computer (/), 2. the home folder of all users, 3. just your own home folder, or 4. just in your current folder (.), wherever you are. This find search is recursive and will also search inside hidden folders. If you get a "Permission denied" error you will need to use sudo with the find command. Testing this in your /home folder will probably show a lot of .jpg files!

Okay, now a little differently... change -name to -iname and it will find .jpg and .JPG (case no longer matters).

Now, we can add the OR operator (-o) so that your search will look for multiple image types.
Code:
find / -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.bmp'
find /home -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.bmp'
find /home/dimzev -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.bmp'
find . -iname '*.jpg' -o -iname '*.jpeg' -o -iname '*.png' -o -iname '*.bmp'
So, with this pattern above, you can choose which image files you want to search for, and it will not matter whether uppercase or lowercase. I'm sure there are better ways, but this is just an example to get you thinking about how it can be done using the Linux find command.

I've got to run for now, so maybe others will add on to this, or get to the next step: MOVE the files that you have found. You will want to make sure you are careful when moving files. You may have unintended consequences.... like all of your menu icons or desktop icons could be gone! It's always a good idea to create a test folder to hold all the image files that you want to experiment with, and do your work from there, and not from the root (/).

Cheers
 

dimzev

New Member
Hello @Tolkem , Hello @atanere ,
thenk you for your answers and your attention...
i am new in terminal command and i need large help-support.
i use ubuntu based distros
i use this command for test:
find /home/kub/Desktop/orange -iname '*.JPG' -exec cp {} /home/kub/Desktop/imagesfromorange/ \;
for ',png' extensions repeat above command
and change cp to mv for move ...thanks for :(MOVE the files that you have found. You will want to make sure you are careful when moving files. You may have unintended consequences.... like all of your menu icons or desktop icons could be gone! It's always a good idea to create a test folder to hold all the image files that you want to experiment with, and do your work from there, and not from the root (/).

how can add others extension in one command?

how can send the copy to folder not exist and make with command ?

is my command right ? can i use in any folder (hard drive ,usb , usb to usb)?


thank you again!!!
 

atanere

Well-Known Member
how can add others extension in one command?
The OR operator (-o) that I showed above is one way. It finds JPG or JPEG or PNG or BMP... and you can add others. This isn't a great way though because I'm a newbie with command line work too. It works somewhat, but at least it gets you thinking about what your doing, and how these commands function.

Glad you found the -exec function already too... that's where I was going next. I tried creating similar test folders with images inside and having the command copy them to another folder, but I haven't worked out the bugs yet. My version only seems to copy one image and not the rest.

Unfortunately, I'm out of time again and have to leave for work (night shift). I think someone will point out one or more much better methods though, but keep experimenting and see what you can learn on your own as well. I'm pretty sure you will be able to copy the images to USB too, but you may have to know the explicit path to make that work right.

Cheers
 

JasKinasis

Well-Known Member
Your best answer will probably come from @JasKinasis
Oh hello!
@dimzev - Stan's got most of the answer mapped out there for you.

To finish things up - If you're searching for several different file-types using the OR operator (-o) and you want to apply some action using -exec, or -execdir - you should enclose the statements containing the regexes for the different files with brackets \( and \) - to group them all together.
e.g.:
Code:
find /path/to/search/ -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.bmp" \) -exec mv {} /path/to/move_to/ \;
That would apply the mv action to all files that were found - of ALL of the specified file-types.
NOTE: in the above example - /path/to/search/ is the path you want to search - so substitute that with the actual path.
And likewise, /path/to/move_to/ is the directory you want to move any found files to. Again - substitute that for the actual path to the directory you want to move the found files to.
The {} is a place-holder in the -exec command for the paths to any of the found files.
And the \; marks the end of the -exec command.

If you did it without the brackets like this:
Code:
find /path/to/search/ -type f -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.bmp" -exec mv {} /path/to/move_to/ \;
For some reason - the mv action specified in -exec will only be applied to the results from the files that matched the last regex ("*.bmp"). So only the bitmap files would be moved.
Now, don't ask me why this is the case - it just is! I'll be upfront and admit - I haven't looked deep enough into the man-pages for find to work out why this happens. This is just something that I've found out through experience using find with -exec.

So, if you are searching for multiple file-types (or files that match multiple regexes) - you need to group them all together if you plan to use them with -exec, or -execdir.

Also, If you wanted to search several different directories, you can do that in one command too!
Simply list the paths to search before the -type:
Code:
find /path/to/search/ /another/path/to/search/ /some/other/path/ -type f \( -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.bmp" \) -exec mv {} /path/to/move_to/ \;
 

dimzev

New Member
Thank you very much @JasKinasis for your answer!!!
can you tell me one more think please?
if i want separate images from each photo machine ...how can make this?
(from my phone not my camera..)
thank you again...!!!
 

Akshat Tripathi

New Member
From a specific file I want find all images(JPG,jpg,png,...) and move (not copy) all this images to a new folder

Please give me the command in terminal
If I want copy from this images in a usb how above command change?

Please give me a help
You must have got your answer by now. Additionally you can use locate command also to find files.


This link may help you. Good luck.
 

JasKinasis

Well-Known Member
Thank you very much @JasKinasis for your answer!!!
can you tell me one more think please?
if i want separate images from each photo machine ...how can make this?
(from my phone not my camera..)
thank you again...!!!
So you mean you want to move all images from several different devices and move them to a separate destination for each device?

If so, it would probably be best to write a script and call the find command once per device and specify a separate search directory and destination directory for each device.

Because the search path and destination paths are the only thing that will vary, you could put the find command into a function and then call the function the required number of times.

e.g.
backupImages.sh
Code:
#!/usr/bin/env bash

# MoveImages - a bash function which takes two parameters
# $1 is the path to the device (the search path)
# $2 is the path to the backup directory for the device
# image files found in $1 are moved to $2
function MoveImages
{
    # Check the search directory exists
    if [ ! -d "$1" ]; then
        # display an error message and quit if not found
        echo "device $1 is not found!" >&2
        exit 1;
    fi

    # If destination directory does not exist create it
    if [ ! -d "$2" ]; then
        mkdir -p "$2"
        #TODO: Check that mkdir succeeded!
    fi

    # find and move files
    find "$1" -type f -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.bmp" -exec mv {} "$2" \;
}

# Now call the MoveImages function, passing the appropriate search paths and destination directories.
MoveImages /path/to/device1/ /path/to/backup/device1/
MoveImages /path/to/device2/ /path/to/backup/device2/
MoveImages /path/to/device3/ /path/to/backup/device3/
# etc etc.
# Go nuts - add as many as you like!
IMPORTANT: Replace ALL of the paths in the calls to MoveImages in the above script with valid paths for your machine.

ALSO NOTE: The above would call MoveImages sequentially. Which could take a long time to complete if you have a lot of devices/search directories.


To speed things up you could take advantage of your PC's multiprocessing capabilities by using GNU parallel (which should be available in the repos of ALL good distros - check with your package manager of choice!).

So we'll make a new version of the script that uses GNU parallel

First up - we'd need to put the calls to MoveImages into a separate text-file that will be read and used by GNU parallel to start our jobs.

e.g.
backupJobs.txt:
Code:
MoveImages /path/to/device1/ /path/to/backup/device1/
MoveImages /path/to/device2/ /path/to/backup/device2/
MoveImages /path/to/device3/ /path/to/backup/device3/
IMPORTANT:
As with before, it is crucial that you ensure that all of the paths are valid paths for your system!

And again - add as many calls to MoveImages as you like in the job-file.

And now our new script - backupImages2.sh:
Code:
#!/usr/bin/env bash

# MoveImages a bash function which takes two parameters
# $1 is the path to the device (the search path)
# $2 is the path to the backup directory for the device
# image files found in $1 are moved to $2
function MoveImages
{
    # Check the search directory exists
    if [ ! -d "$1" ]; then
        # display an error message and quit if not found
        echo "device $1 is not found!" >&2
        exit 1;
    fi

    # If destination directory does not exist create it
    if [ ! -d "$2" ]; then
        mkdir -p "$2"
        #TODO: Check that mkdir succeeded!
    fi

    # find and move files
    find "$1" -type f -iname "*.jpg" -o -iname "*.jpeg" -o -iname "*.png" -o -iname "*.bmp" -exec mv {} "$2" \;
}

# export the function so parallel can use it
export -f MoveImages

# run our backup-jobs via GNU parallel
parallel --bar --jobs 4 < backupJobs.txt

The new script will cause GNU parallel to read through backupJobs.txt and each line in the text file will be started as a separate job.

NOTES:
The --bar option to GNU parallel causes it to display a progress bar, listing various information about the status of the jobs.
The --jobs option allows you to set the maximum number of jobs to be ran. If you have a ton of processor cores, you can specify how many to use. I'm not sure how many are used if you omit the --jobs option. I think it might try to use all unused/available cores.

I hope that has helped!
 
Last edited:

Staff online

Members online


Top