You can use https://www.shellcheck.net/ to check your syntax, and learn about indentation.  It will suggest some modifications to your code.   Excellent suggestions also by @KamilCuk in the comments.
When you need to do something recursively in sub-directories, you can always use find with option -exec.  You use {} to specify that the command should be applied to each file (or directory) that matches your find options.
This would do the trick: find $from -type f -name "*.txt" -exec cp {} $to \; -print
- -type f: find all files
- -exec cp {} $to \;: for each file that is found (- {}), copy it to the $to directory.- \;delimits the end of the command for option- -exec.
- -name "*.txt": if you want to filter by file name (here the extension .txt must be present to match).
- -print: if you want to see which files are copied, as it goes through your directories.
Note also that find will work even if you have a huge number of sub-directories, or a very large number of files in them.  ls sometimes fails, or takes an enormously long time to output large number of files.