迭代$ @的值

时间:2016-06-28 01:08:34

标签: bash special-variables

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

./bash_script file1 file2 file3

$@为我提供了给脚本的所有文件但是如何迭代这些文件?

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

2 个答案:

答案 0 :(得分:5)

诀窍是双引号,如同"$@"

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

相当于:

printf ' ->%s\n' "a b" c "d e"

如果上面的$@ 不是双引号,那么您将获得:

 printf ' ->%s\n' a b c d e

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

$ @ vs. $ *

对于任何数组上的任何 @ - 扩展,双引号都是这样的:

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

相反, * - 扩展(例如,$*${foo[*]})将使用$IFS的第一个字符将数组项加入单个字符串:

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

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

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

在for循环中尝试迭代$ @:

"$@"数组很特别。如果你想在for循环中迭代"$@",那么你可以缩写

 for variable_name in "$@"; do
   ...
 done

as

 for variable_name; do 
 done

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

这甚至也适用于仅支持POSIX的shell(破折号,bourne shell ),它们不具备数组变量但支持"$@""$*

答案 1 :(得分:2)

要迭代它们,请使用双引号$@,如下所示:

for arg in "$@" ; do
    echo "--> ${arg}"
done

for arg in "$@"也可以写为for arg(甚至是for arg in),因为bash手册页指出:

  

for name [ [ in [ word ... ] ] ; ] do list ; done

     blah blah blah

     

如果省略in字,for命令对每个设置的位置参数执行一次列表。

但是,我更喜欢显式变体。

以下成绩单显示了这一点:

pax: testprog.sh 1 2 3 '4 5' '' '6 7 8' "9"
--> 1
--> 2
--> 3
--> 4 5
--> 
--> 6 7 8
--> 9

另外,关于使用catawk来修改文件的评论可能会降低使用cat奖励&#34的无用愤怒34;人群: - )

如果您正在考虑以下内容:

cat "${fspec}" | awk 'do something'

然后cat完全没必要。您可以改为使用:

awk 'do something' "${fspec}"

我通常不担心运行额外流程的(小)低效率,但有些人会这样做。