我面临一个乍看之下很容易解决的特定问题。
如果我在bash shell中键入与不同文件相对应的通配符:
$ myfile=probe_*.txt
然后执行:
$ echo $myfile
我得到与通配符匹配的所有文件的列表,即:
$ probe_GCph.txt probe_GCsp.txt probe_GCsp_WL_GCph.txt probe_GCsp_XC.txt probe_GCsp_XC_WL_GCph.txt probe_WL.tx
但是现在,我想将通配符probe_*.txt
作为参数$2
放入函数中。
目前,如果我使用bash函数:
function multiple_files { myfile=$2
echo $1
echo $3
echo $myfile
}
然后,在以下执行中:
$ multiple_files . $myfile dir/
然后,我只获得为bash函数的定义中的第三个回显(probe_GCph.txt
)打印的第一个文件名echo $myfile
。
如何传递文件的通配符名称作为参数(此处为$ 2),并能够将其扩展以列出bash函数中对应的所有文件名?
[仅考虑第一个扩展文件为probe_GCph.txt
的参数$ 2与将通配符作为参数$ 2传递而不扩展它之间似乎存在冲突。
如何规避此问题?
问候
双引号可避免扩展外壳范围,但仍允许替换外壳变量。值得一提的是,单引号既可以防止glob(或类似扩展的通配符)又可以防止变量插值。
TL; DR:
以这种方式调用您的函数:
multiple_files . "$myfile" dir/
要在函数内传递通配符,您需要转义特殊字符或在引号中包含通配符序列。
$ ls
f1 f2 f3
$ function multiple_files { myfile=$2; echo $1; echo $2; echo $myfile;}
$ multiple_files '*' f\*
f1 f2 f3
f1 f2 f3
f1 f2 f3
如果您不转义通配符,则会在调用该函数之前将其展开
$ multiple_files f*
f1
f2
f2
要在函数内部打印通配符,您还需要在引号中包含变量。 eval
也有一些技巧:
$ function multiple_files { myfile=$2; echo $1; eval echo "$2"; echo "$2"; echo "$myfile"; eval echo "$myfile";}
$ multiple_files '*' f\*
f1 f2 f3
f1 f2 f3
f*
f*
f1 f2 f3
编写函数以接受多个参数,而不只是一个。这是大多数其他工具的工作方式(cp / mv / ls / grep / sed仅举几例):
multiple_files() {
first="$1"
last="${@: -1}"
files=( "${@:2:$#-2}" )
echo "The first thing was $first"
echo "The last thing was $last"
for file in "${files[@]}"
do
echo "One of the files is $file"
done
}
multiple_files . probe_*.txt dir/
这导致:
The first thing was .
The last thing was dir/
One of the files is probe_GCph.txt
One of the files is probe_GCsp.txt
One of the files is probe_GCsp_WL_GCph.txt
One of the files is probe_GCsp_XC.txt
如果您实际需要模式本身,或者您想接受多个模式并将它们分开,则可能需要引用其他答案中所述的glob。