I'm writing script for my own needs to sort Downloads folder on my mac in bash. I pass to the function parameters: source directory, destination directory and array of file extensions I want to move. My problem is that when function is in "find" line then it copies just one file with that extension but when I remove all variables and I put parameters directly then it works fine. What's going on ?
function moveFaster(){
clear
src=1ドル
dst=2ドル
typ=3ドル
if [ ! -d $dst ]
then
mkdir $dst
fi
for i in "${typ[@]}"
do
find $src -name "${i}" -exec mv {} ${dst} \;
done
}
-
Put 'set -x' towards the top, so it will echo everything it does.Zoredache– Zoredache2011年10月02日 19:00:55 +00:00Commented Oct 2, 2011 at 19:00
1 Answer 1
Each argument to a function is a scalar, and you're trying to pass an array. When you write
a=(foo bar qux)
moveFaster "$src" "$dst" "${a[@]}"
then moveFaster receives five arguments: $src, $dst, foo, bar and qux. If you write moveFaster "$src" "$dst" "$a" then only the first element of the array is passed to the function, because $a on its own expands to the first element of the array. Furthermore, your assignment to typ makes it a scalar variable.
Since you're passing a single array to the function, you can declare that it consists of all the remaining parameters.
moveFaster () {
src="1ドル"
dst="2ドル"
shift 2
typ=("$@")
...
}
On a related note, your script will fail spectacularly if any of the file names involved contains whitespace or globbing characters (?*\[). To avoid this, respect this simple shell programming rule: always put double quotes around variable substitutions (unless you understand why they must not be present in a particular case).
function moveFaster(){
src="1ドル"
dst="2ドル"
typ=("$@")
if [ ! -d "$dst" ]; then mkdir -- "$dst"; fi
for i in "${typ[@]}"; do
find "$src" -name "${i}" -exec mv {} "${dst}" \;
done
}
As an aside, you can do this reasonably easily with bash features alone, if you have bash version 4 or above. The extglob option allows extended glob patterns such as @(PATTERN1|PATTERN2). The globstar option allows **/PATTERN to match files whose name matches PATTERN in subdirectories recursively.
shopt -s extglob globstar
mkdir -p /common/destination/directory
mv /path/to/source/**/@(*.txt|*.html|README) /common/destination/directory