4

使用$@您可以对 bash 中的文件列表执行操作。例子:

脚本.sh:

#!/bin/bash
list=$@
for file in $list; do _commands_; done

然后我可以调用这个程序

~/path/to/./script dir1/{subdir1/*.dat,subdir2/*}

该参数将扩展为多个参数,变为$list. 但现在我想要其他参数,比如 1 美元、2 美元,而这个清单是 3 美元。所以我希望在dir1/{subdir1/*.dat,subdir2/*}脚本内部进行扩展,而不是成为许多参数。在命令行上,您可以这样做:

find dir1/{subdir1/*.dat,subdir2/*}

并获得所需的输出,即文件列表。所以我尝试了这样的事情:

arg1=$1
arg2=$2
list=$(find $3)
for file in $list; do _commands_; done
...

调用:

~/path/to/./script arg_1 arg_2 'dir1/{subdir1/*.dat,subdir2/*}'

但没有成功。非常感谢有关如何将此列表扩展为脚本内的变量的一些帮助!:)

编辑:所以下面的答案给出了使用这些命令的解决方案:

arg1="$1"
arg2="$2"
shift 2

for f in "$@"; do echo "processing $f"; done;

但是出于好奇,是否仍然可以将字符串传递dir1/{subdir1/*.dat,subdir2/*}find脚本内的命令(或任何具有相同目的的命令),而不使用$@, 并以这种方式获取列表?这可能很有用,例如,如果最好将列表作为不是第一个或最后一个参数,或者在某些其他情况下,即使它需要转义字符或引用参数。

4

2 回答 2

4

您可以在脚本中包含此代码:

arg1="$1"
arg2="$2"
shift 2

for f in "$@"; do echo "processing $f"; done;

然后将其称为:

~/path/to/script arg_1 arg_2 dir1/{subdir1/*.dat,subdir2/*}

Usingshift 2会将位置参数移动 2 个位置,从而生成$3as$1$4as$2等。然后您可以直接调用$@以迭代其余参数。

根据help shift

shift: shift [n]

  Shift positional parameters.

  Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
于 2015-02-02T14:57:51.117 回答
0

shell 扩展是由 shell 执行的,甚至在你的脚本被调用之前。这意味着您必须引用/转义参数。在脚本中,您可以使用eval来执行扩展。

#!/bin/bash
arg1="$1" ; shift
arg2="$2" ; shift
eval "list=($@)"
for q in "${list[@]}" ; do echo "$q" ; done

$ ./a 123 456 'a{b,c}' 'd*'
ab ac d.pl docs

在您的示例中,我没有看到在脚本中进行扩展的意义。

#!/bin/bash
arg1="$1" ; shift
arg2="$2" ; shift
list=("$@")
for q in "${list[@]}" ; do echo "$q" ; done

要不就

#!/bin/bash
arg1="$1" ; shift
arg2="$2" ; shift
for q in "$@" ; do echo "$q" ; done

$ ./a 123 456 a{b,c} d*
ab
ac
d.pl
docs
于 2015-02-02T14:59:39.240 回答