我正在编写脚本以满足我自己的需要,以便在 bash 中对我的 mac 上的下载文件夹进行排序。我传递给函数参数:源目录、目标目录和要移动的文件扩展名数组。我的问题是,当函数在“查找”行中时,它只复制一个具有该扩展名的文件,但是当我删除所有变量并直接输入参数时,它可以正常工作。这是怎么回事 ?
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
}
Run Code Online (Sandbox Code Playgroud)
函数的每个参数都是一个标量,而您正在尝试传递一个数组。当你写
a=(foo bar qux)
moveFaster "$src" "$dst" "${a[@]}"
Run Code Online (Sandbox Code Playgroud)
然后moveFaster接收五个参数:$src
,$dst
,foo
,bar
和qux
。如果你写,moveFaster "$src" "$dst" "$a"
那么只有数组的第一个元素被传递给函数,因为$a
它自己扩展到数组的第一个元素。此外,您的赋值typ
使其成为标量变量。
由于您将单个数组传递给函数,因此您可以声明它包含所有剩余参数。
moveFaster () {
src="$1"
dst="$2"
shift 2
typ=("$@")
…
}
Run Code Online (Sandbox Code Playgroud)
与此相关的是,如果任何涉及的文件名包含空格或通配符 ( ?*\[
) ,您的脚本将严重失败。为了避免这种情况,请遵守这个简单的 shell 编程规则:始终在变量替换周围加上双引号(除非您明白为什么它们不能出现在特定情况下)。
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
}
Run Code Online (Sandbox Code Playgroud)
顺便说一句,如果您有 bash 版本 4 或更高版本,您可以仅使用 bash 功能就可以相当容易地做到这一点。该extglob
选项允许扩展 glob 模式,例如@(PATTERN1|PATTERN2)
. 该globstar
选项允许**/PATTERN
匹配名称PATTERN
在子目录中递归匹配的文件。
shopt -s extglob globstar
mkdir -p /common/destination/directory
mv /path/to/source/**/@(*.txt|*.html|README) /common/destination/directory
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
257 次 |
最近记录: |