如果我想迭代所有参数,它就像for i in "$@"; do ...
一样简单。但是,让我们说我想从第二个论点开始,并且还要使用参数'一些基本计算的位置。
作为一个例子,我想将这些命令缩短为一个循环:
grep -v 'foobar' "$2" | grep -f $file > output1.txt
grep -v 'foobar' "$3" | grep -f $file > output2.txt
grep -v 'foobar' "$4" | grep -f $file > output3.txt
grep -v 'foobar' "$5" | grep -f $file > output4.txt
我尝试了许多变体,例如for i in {2..5}; do grep -v 'foobar' "$$i" | grep -f $file > output$(($i-1)).txt; done
;然而,似乎bash扩张并不像这样工作。
编辑:
似乎我犯了一个错误,没有强调我需要利用论证的位置/数字(即来自$2
的2)。这很重要,因为输出文件稍后会在脚本中单独使用。到目前为止,所有提供的答案似乎都是正确的,但我不知道如何使用它们来利用论证"数字"。
答案 0 :(得分:5)
如果你不想要转移第一个不需要的参数,你可以使用indirection expansion:
for i in {2..5}; do
echo "${!i}"
done
答案 1 :(得分:1)
您只需使用shift
移动位置参数一次(从而放弃$1
):
fn() { arg1="$1"; shift; for arg; do echo "$arg"; done; }
将其命名为:
fn val1 val2 val3 val4
<强>输出:强>
val2
val3
val4
答案 2 :(得分:1)
已经有正确的答案,另一种方式可能是:
a = :calendar.universal_time() |> Timex.DateTime.from_erl
b = {{2016, 4, 5}, {13, 17, 29}} |> Timex.DateTime.from_erl
if Timex.Comparable.diff( a, b, :days ) > 30 do
# ...
end
答案 3 :(得分:1)
您也可以直接使用数组索引:
#!/bin/bash
for i in "${@:2}"; do
echo "$i"
done
将迭代以第二个参数开头的参数。它还会在引用时保留参数中的空格。 e.g。
$ bash args.sh one two "three four" five
two
three four
five
答案 4 :(得分:0)
以上答案是正确的。另一种方法:
a=("${@:2}")
for i in ${!a[@]}; do
echo "$i = ${a[i]}"
done
答案 5 :(得分:0)
$@
类似于一个数组,差别很小,它是基于一个而不是从零开始($0
是shell或shell脚本的名称),它可以'被编入索引(${@[1]}
无法访问$1
)。您可以使用parameter expansion(更具体地说:子字符串扩展)来访问位置参数的子集:
$ set arg1 arg2 arg3 arg4 arg5 # Set $1, $2, $3, $4, $5
$ for i in "${@:2}"; do echo "$i"; done
arg2
arg3
arg4
arg5
请注意,这实际上不允许您使用参数的索引和参数本身。要做到这一点,您必须将位置参数转换为常规数组并将索引偏移量处理为1($1
将具有索引0),或使用间接扩展(请参阅andlrc's answer)
第一种方法的例子:
$ set arg1 arg2 arg3 arg4 arg5
$ args=("$@")
$ for i in 3 2 5 1 4; do echo "\$$i is ${args[$((i-1))]}"; done
$3 is arg3
$2 is arg2
$5 is arg5
$1 is arg1
$4 is arg4
显然,${args[$((i-1))]}
相当混乱,但它有效。
附注:如果您想访问所有位置参数,可以使用方便的简写:
$ for i; do echo "$i"; done
arg1
arg2
arg3
arg4
arg5
没有for
部分的 in
遍历所有位置参数(请参阅manual)。