迭代$ @的值

use*_*672 2 bash special-variables

我想迭代给bash脚本的参数,例如:

./bash_script file1 file2 file3
Run Code Online (Sandbox Code Playgroud)

$@ 给了我给脚本的所有文件但我如何迭代文件?

我想cat每个文件并删除内容使用awk(我知道如何做到这一点,这是解开包装$@让我感到困惑).

PSk*_*cik 5

诀窍是双引号它作为"$@".

foo(){
   printf ' ->%s\n' "$@";
}
foo "a b" c "d e"
Run Code Online (Sandbox Code Playgroud)

相当于:

printf ' ->%s\n' "a b" c "d e"
Run Code Online (Sandbox Code Playgroud)

如果$@上面的内容不是双引号,那么你会得到:

 printf ' ->%s\n' a b c d e
Run Code Online (Sandbox Code Playgroud)

由于$IFS字符上的单词拆分($IFS默认为' '$'\t'$'\n',即空格,制表符和换行符)


$ @ vs. $*

对于任何数组上的任何@ -expansion,双引号的工作方式如下:

$ foo=( "a b" c "d e" )
$ printf ' ->%s\n' "${foo[@]}"
   ->a b
   ->c
   ->d e
Run Code Online (Sandbox Code Playgroud)

与此相反,*-expansions(例如$*,${foo[*]})将使用的第一个字符$IFS加入一个阵列的项组合成一个字符串:

$ foo=( "a b" c "d e" )
$ ( IFS=:; printf ' ->%s\n' "${foo[*]}" )
 ->a b:c:d e
Run Code Online (Sandbox Code Playgroud)

如果不加引号,将再次拆分这个非常IFS字符:

$ foo=( "a b" c "d e:f:g" )
$ ( IFS=:; printf ' ->%s\n' ${foo[*]} ) 
 ->a b
 ->c
 ->d e
 ->f
 ->g
Run Code Online (Sandbox Code Playgroud)

在for循环中迭代$ @的技巧:

"$@"阵列是特殊的.如果你想"$@"在for循环中迭代,那么你可以缩写

 for variable_name in "$@"; do
   ...
 done
Run Code Online (Sandbox Code Playgroud)

 for variable_name; do 
 done
Run Code Online (Sandbox Code Playgroud)

跳过循环的in something一部分for意味着in "$@".

这甚至在仅POSIX的shell(dash,bourne shell)中也有效,它们没有数组变量但是支持"$@""$*.