5

Let's say I have a file with a unique name (e.g.Screenshot20180509143013.png) that I wish to copy to /media/SD256.

The file /media/drive1/Users/name/Pictures/Screenshots/Screenshot20180509143013.png is tangled in some sub-directory levels, and I wish not to navigate to /media/drive1/Users/name/Pictures/Screenshots/ to find that file with the unique name.

Instead, I wish to run a command while my working directory is /media/drive1/, which looks similar to:

copy --find-filename-then-copy Screenshot20180509143*3.png /dev/media/SD256/DestinationFolder

Is there such a command that can first find the file and then copy?

  • If any of the answers solved your problem, please accept it by clicking the checkmark next to it. Thank you! – Jeff Schaller May 16 '18 at 10:50
14

Using find:

find . -type f -name Screenshot20180509143013.png -exec cp {} /dev/media/SD256/DestinationFolder ';'

This would find all regular files in or below the current directory, whose names are exactly Screenshot20180509143013.png. The found files would be copied to /dev/media/SD256/DestinationFolder. If there are multiple files with the same name (which you say there aren't), the files would overwrite each other in the destination directory.

  • 1
    If the file is unique it would help to use the -quit action to tell find to stop the search once it found a result and performed the -exec action. Or is that a non-standard action? – David Foerster May 9 '18 at 22:40
14

With zsh or fish or ksh -o globstar or bash -O globstar (or after shopt -s globstar in bash) or tcsh after set globstar or yash -o extended-glob:

cp -- **/Screenshot20180509143*3.png /dev/media/SD256/DestinationFolder

globstar, with the ** syntax, does a recursive search; if the remainder of the glob (filename pattern) is unique, then you'll get the results you want. Note that I copied the ...3*3 from your example, and not the e.g. filename Screenshot20180509143013.png from earlier in the question.

Note that:

  • fish and versions of bash prior to 4.3 will following symlinks when recursing. With zsh, tcsh or yash, you can use *** instead of ** to get that behaviour.
  • fish will not find the file if it's in the current directory.
  • Hidden files and files in hidden directories will not be considered. Many shells have a dotglob option to reenable them. See also the (D) glob qualifier in zsh.
  • In zsh you may also want to add ([1]) at the end of the pattern. [1] is a glob qualifier to copy only the first matching file.
  • the -i option to cp can also guard against accidental overwrite if the file is found in several directories.
2

ZSH

If you are using zsh, you can use cp with zsh's globbing:

cp **/Screenshot20180509143013.png /dev/media/SD256/DestinationFolder

**/Screenshot20180509143013.png will try to find Screenshot20180509143013.png recursively from the current directory.

General purpose

For general purpose, you can always use find + cp:

cp "$(find ./ -type f -name "<picture_name>" )" "<destination>"

find - Search for a file.

./ - Search in the current directory.

-type f - Limit the search for the regular files.

-name "<picture_name>" - Search for a file with name <picture_name>
(* in <picture_name> can be used to match any sequence)

"$(find ./ -type f -name "<picture_name>" )" - Replace this part of code with stdout of find command.

cp "$(find ./ -type f -name "<picture_name>" )" <destination> - Copy file with path gotten from "$(find ./ -type f -name "<picture_name>" )" to <destination>.

  • @Jeff Schaller Why would you edit it like this? It's uglier now :D – Iskustvo May 9 '18 at 13:53
  • 1
    There were explicit file and directory names mentioned in the question, and using < and > as placeholders in shell commands may me confusing. – Kusalananda May 9 '18 at 13:55
  • Sorry about that; I believe it's more helpful to the asker to solve their problem directly. Feel free to revert the change if you don't like it. – Jeff Schaller May 9 '18 at 13:56
  • Well, I tried to explain it a bit and that made it harder, but nevermind, thanks for the effort! – Iskustvo May 9 '18 at 14:01
  • @Iskustvo Possible way to do it? Something like /path/to/file or /path/to/pattern (or whatever - I think you know what I'm trying to say). You could add something to it too: you give the general syntax like that but you also give an example with the precise name/glob/whatever? – Pryftan May 9 '18 at 20:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.