在bash脚本中迭代参数并使用它们的数字

时间:2016-05-05 14:54:17

标签: bash loops command-line

如果我想迭代所有参数,它就像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)。这很重要,因为输出文件稍后会在脚本中单独使用。到目前为止,所有提供的答案似乎都是正确的,但我不知道如何使用它们来利用论证"数字"。

6 个答案:

答案 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)。