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.