This should do:
#!/bin/bash [[ -n "$1" ]] || { echo >&2 'Give me an argument!'; exit 1; } destdir=$(readlink -m -- "$1") [[ "$destdir" == *\** ]] && { echo >&2 "Sorry, I'm in the stupid situation where the destination dir contains the \`*' character. I can't handle this."; exit 1; } mkdir -pv -- "$destdir" || { echo >&2 "Couldn't create directory \`$destdir'. Sorry."; exit 1; } find "$HOME" -path "$destdir" -prune -o \( -name '*.txt' -exec cp -iv -t "$destdir" -- {} \; \)
Pro: works with files with spaces or funny characters in their name (unlike yours) (except for one stupid case, see below).
Con: As ormaaj noted in a comment, this may fail if the name of your destination path contains a wildcard character * . This case is safely taken into account, and the script exquisitely exits if it ever happens.
Explanations.
- Give an argument to this script. It can be absolute relative to the current directory.
readlink , with the -m option, it will take care to translate this into an absolute path: the destdir variable. - The
$destdir is created with the parents, if applicable. - In the home directory, if we find the
$destdir , we truncate this branch, otherwise we will search for all *.txt files and copy them to $destdir .
Once again, this script is 100% safe with respect to file names with funny characters: spaces, newlines or hyphens, with the exception of the wildcard character * in the name of the target directory, but this case is safely handled by an elegant output rather than potentially twisting files.
source share