如何在 Bash 脚本中使用 $* 并省略某些输入变量(例如 $1 和 $2)?

如何在 Bash 脚本中使用 $* 并省略某些输入变量(例如 $1 和 $2)?

例如,

elif [[ $append = $1 ]]
then
  touch ~/directory/"$2".txt
  echo "$variable_in_question" >> ~/directory/"$2".txt

要创建一个包含以下所有输入的文本文件"$2",或附加一个包含以下所有输入的现有文本文件"$2",我该用什么来代替"$variable_in_question"第 4 行?

我基本上想要"$*",但省略"$1""$2"

答案1

您可以使用bash参数扩展指定范围,这也适用于位置参数。对于$3$n它将是:

"${@:3}" # expands to "$3" "$4" "$5" …
"${*:3}" # expands to "$3 $4 $5 …"

请注意,$@和都$*忽略第一个参数$0。如果你想知道在你的案例中应该使用哪一个:它是非常你可能想要一个带引号的$@$*除非你明确希望单独引用这些论点。

您可以按照如下方式尝试:

$ bash -c 'echo "${@:3}"' 0 1 2 3 4 5 6
3 4 5 6
$ echo 'echo "${@:3}"' >script_file
$ bash script_file 0 1 2 3 4 5 6
2 3 4 5 6

请注意,在第一个示例中,$0填充的是第一个参数0,而在脚本中使用时,$0则填充的是脚本的名称,如第二个示例所示。脚本的名称bash当然第一个参数,只是通常不被视为第一个参数——对于可执行并“直接”调用的脚本也是如此。因此,在第一个示例中,我们有$0= 0$1=1等,而在第二个示例中,我们有$0= script_file$1= 0$2=1等;${@:3}选择以 开头的每个参数$3

可能范围的一些其他示例:

 # two arguments starting with the third
$ bash -c 'echo "${@:3:2}"' 0 1 2 3 4 5 6
3 4
 # every argument starting with the second to last one
 # a negative value needs either a preceding space or parentheses
$ bash -c 'echo "${@: -2}"' 0 1 2 3 4 5 6
5 6
 # two arguments starting with the fifth to last one
$ bash -c 'echo "${@:(-5):2}"' 0 1 2 3 4 5 6
2 3

进一步阅读:

答案2

您可以使用shift内置函数:

$ help shift
shift: shift [n]
    Shift positional parameters.

    Rename the positional parameters $N+1,$N+2 ... to $1,$2 ...  If N is
    not given, it is assumed to be 1.

    Exit Status:
    Returns success unless N is negative or greater than $#.

例如给定

$ cat argtest.bash 
#!/bin/bash

shift 2

echo "$*"

然后

$ ./argtest.bash foo bar baz bam boo
baz bam boo

答案3

通常,您可以将位置参数复制到一个数组,删除该数组的任意索引,然后使用该数组扩展为您想要的索引,而不会丢失原始参数。

例如,如果我想要除第一、第四和第五个参数之外的所有参数:

args=( "$@" )
unset args[0] args[3] args[4]
echo "${args[@]}"

在副本中,索引移动 1,因为$0不是 的一部分$@

相关内容