Bash:将通配符作为shell脚本的参数,并能够对其进行扩展

问题描述 投票:0回答:3

我面临一个乍看之下很容易解决的特定问题。

如果我在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传递而不扩展它之间似乎存在冲突。

如何规避此问题?

问候

bash wildcard
3个回答
0
投票

双引号可避免扩展外壳范围,但仍允许替换外壳变量。值得一提的是,单引号既可以防止glob(或类似扩展的通配符)又可以防止变量插值。

TL; DR:

以这种方式调用您的函数:

multiple_files . "$myfile" dir/

0
投票

要在函数内传递通配符,您需要转义特殊字符或在引号中包含通配符序列。

$ 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

0
投票

编写函数以接受多个参数,而不只是一个。这是大多数其他工具的工作方式(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。

© www.soinside.com 2019 - 2024. All rights reserved.