0

I wrote a script in bash that should read the contents of a text file, look for the corresponding files for each line, and copy them to another folder. It's not copying all the files, only two, the third and the last.

#!/bin/bash

filelist=~/Desktop/file.txt
sourcedir=~/ownCloud2
destdir=~/Desktop/file_out

while read line; do
        find $sourcedir -name $line -exec cp '{}' $destdir/$line \;
echo find $sourcedir -name $line
sleep 1
done < "$filelist"

If I use this string on the command line it finds me and copies the file.

find ~/ownCloud2 -name 123456AA.pdf -exec cp '{}' ~/Desktop/file_out/123456AA.pdf \;

If I use the script instead it doesn't work.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
vincenzo
  • 1
  • 1
  • 2
    Please paste your script at [shellcheck.net](http://www.shellcheck.net/) and try to implement all recommendations made there. – Cyrus Dec 12 '22 at 02:24
  • `code`#!/bin/bash filelist=~/Desktop/file.txt sourcedir=~/ownCloud2 destdir=~/Desktop/file_out while read -r line; do find "$sourcedir" -name "$line" -exec cp '{}' $destdir/"$line" \; echo find $sourcedir -name "$line" done < "$filelist"`code` I made the suggested changes but it doesn't work! – vincenzo Dec 12 '22 at 02:57
  • 2
    Please [edit] your question and replace the code with the updated version. It's unreadable as a comment. – John Kugelman Dec 12 '22 at 03:02
  • 1
    Three notes, additional to what John said above (which you should consider reiterated): (1) Run `bash -x yourscript`, to make bash log what it's doing. (2) If your cp supports `-v`, add that too so you can see what it's trying to do. (3) The details of your filenames matter. If they contain either backslashes or leading/trailing whitespace, f/e, then you'll have bugs that replacing your loop with `while IFS= read -r line; do` will fix. – Charles Duffy Dec 12 '22 at 03:06
  • In the xtrace logs, in particular, you can see if `find` is being run at all, and whether the strings it's being passed at runtime match what you think they should be. `echo` is not a suitable tool for this use case; it prints data ([often badly](https://stackoverflow.com/questions/29378566/i-just-assigned-a-variable-but-echo-variable-shows-something-else)) but ignores syntax, and having the syntax right is critical. – Charles Duffy Dec 12 '22 at 03:07
  • There are other places where details you aren't giving us can matter as well. For example, if your `filelist` contains `"123456AA.pdf"` _with the quotes_, then `find` looks for files with quotes as part of the name. This is just one example of the many things that could possibly go wrong where you aren't giving us enough information to allow diagnosis; part of why we ask for `bash -x` logs is that they find assumptions made (in your data format or otherwise) that you didn't think to include in the question. – Charles Duffy Dec 12 '22 at 03:09
  • also, does input `filelist` contain just filenames, or paths? If it contains filenames like `foo.pdf`, then the script is ok, but if it contains `foo/bar.pdf` (i.e., a path) then it wouldn't (necessarily) work, because the target directory wouldn't exist. (I'm looking for reasons why "it works...sometimes".) Also, are there duplicate entries in the input file? And, does a file in the input `filelist.txt` exist in more than one place in the directory `sourcedir`? If so, you're overwriting files in `destdir` (but that wouldn't even work unless those target dirs existed; again `cp -v` might help) – michael Dec 19 '22 at 04:32

1 Answers1

0

I used your exact script and had no problems, for both bash or sh, so maybe you are using another shell in your shebang line.

Use find only when you need to find the file "somewhere" in multiple directories under the search start point.

If you know the exact directory in which the file is located, there is no need to use find. Just use the simple copy command.

Also, if you use "cp -v ..." instead of the "echo", you might see what the command is actually doing, from which you might spot what is wrong.

Eric Marceau
  • 1,601
  • 1
  • 8
  • 11