I have a list of filenames names.list which contains names only. These files are scattered throughout my system in various sub folders but the structure is generally


The constant is spades/filtered

I have used the following command when moving files from one directory

xargs -a file_list.txt cp -t /path/to/dest

And I spotted this thread on using wildcard/ partial file names

find . -path \*content/docs/file.xml

And I tried combining them like so

find . -path \*spades/filtered/ | xargs -a names.list cp -t $HOME/destination/

But I get the following error:

cp: cannot stat `filename': No such file or directory

tldr: I want to copy files using and input list of names only and partial file path


2 Answers 2


Go through the filenames via a for-loop and append them to the find pattern, copy with exec handle:

for i in $(<names.list)
    find . -path \*spades/filtered/"$i" -type f -exec cp -t "$HOME/destination/" {} \;;

Edit: Thanks to Rakesh Sharma`s answer, substituting the loop body with:

find . -mindepth 5 -maxdepth 5 -path "*/spades/filtered/$i" -type f -exec cp -t "$HOME/destination/" {} +;

speeds things up.

  • Hi FloHe, I want to search within the partial directory path the files which are in my list.
    – AudileF
    Commented Jul 18, 2017 at 12:06
  • @AudileF Why do you want to search within the partial dir path when the list file already have them with the partial path as a constant you mentioned earlier on?
    – user218374
    Commented Jul 18, 2017 at 12:12
  • No my list is just names only. There is no path within the list. I see my original question is misleading. Ill change it now.
    – AudileF
    Commented Jul 18, 2017 at 12:15
  • @AudileF: So you have them without the partial dir path prefix in the file names.list? But then it isn't clear in which partial dir path to search for the individual files.
    – FloHe
    Commented Jul 18, 2017 at 12:17
  • 2
    @AudileF You could make the following changes to speed things up; find . -mindepth 5 -maxdepth 5 -path "*/spades/filtered/$i" -type f -exec cp -t "$HOME/destination/" {} +; where you are basically giving a chunk of files to cp rather than just 1 and the min/max-depths allow find to jump right in to the right hierarchy rather than recurse it's way through.
    – user218374
    Commented Jul 18, 2017 at 13:40

You could do away with the for loop and do everything within xargs:

xargs -a names.list -L 1 -I @ find . -path \*/spades/filtered/@ -type f -exec cp -fpvt "$HOME/destination/" {} +

Assuming GNU xargs, find, and cp utilities.

-a will read the filename a line at a time.

-L 1 option makes xargs pass one newline-separated argument to find.

-I @ option will condense that argument in the symbol @ which can be stuck in the utility invoked by xargs, in this case, find. More specifically, the -path option of find is modified by the @ symbol for every line of names.list read.

You must log in to answer this question.

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