use*_*672 2 bash special-variables
我想迭代给bash脚本的参数,例如:
./bash_script file1 file2 file3
Run Code Online (Sandbox Code Playgroud)
$@ 给了我给脚本的所有文件但我如何迭代文件?
我想cat每个文件并删除内容使用awk(我知道如何做到这一点,这是解开包装$@让我感到困惑).
诀窍是双引号它作为"$@".
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)中也有效,它们没有数组变量但是支持"$@"和"$*.