I'm trying to run a for loop that copies all files in a directory and then place them in a backup directory. There are multiple sub-directories with varying names so I thought I should use multiple wildcards so I didn't have to list all of them out and add another for loop in. This is my script



for file in $DIR
        cp "$file"/**/**/*.txt* "$DIR"/backup/"$file"

When I run it though the script can't go into the sub directories and thinks the directory is


Any advice would be greatly appreciated

  • try shopt -s globstar. then a single ** should be enough: eg. /dir/**/*.txt – mosvy Oct 12 '18 at 4:13
  • @mosvy hmm okay that's what I need, but I seem to be getting an error still For example the script says it "cannot create regular file /home/users/data/*backup//home/users/data/S036_20181002’ Is there something with the $file part at the end of my destination path "$DIR"/backup/"$file"? – 762 Oct 12 '18 at 5:00
  • Wildcards in quotes won't expand. – Kusalananda Oct 12 '18 at 7:45
  • Is what you want to do very different from indiscriminatingly copying the whole of /home/users/data to /home/users/data/backup (minus the backup directory itself)? – Kusalananda Oct 12 '18 at 7:51

I think it would be better to use find here:

for FILE in $DIR
    find $DIR -iname '*.txt' -exec cp -fv {} ${DIR}/backup/${FILE} \;

You can add --parents option to cp if you want to preserve directory structure.

| improve this answer | |

If you just want to duplicate /home/users/data under /home/users/data/backup:

rsync -ai --exclude=/backup/ /home/users/data/ /home/users/data/backup

This would also exclude the backup directory itself from getting copied when rerunning the command. Note that the source directory (and the directory in the exclude pattern) should have slashes at the end.

| improve this answer | |

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.