迭代$@的值



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

./bash_script file1 file2 file3

$@给了我所有给脚本的文件,但我如何遍历这些文件?

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

技巧是将"$@"双引号。

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

等价于:

printf ' ->%sn' "a b" c "d e"

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

 printf ' ->%sn' a b c d e

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


$@ vs. $*

对于任意数组:上的任意@-expansion,双引号就像这样工作
$ foo=( "a b" c "d e" )
$ printf ' ->%sn' "${foo[@]}"
   ->a b
   ->c
   ->d e

相反,*-展开(例如,$*, ${foo[*]})将使用$IFS的第一个字符将数组中的元素连接成一个字符串:

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

如果不加引号,它将再次在这个IFS字符上分裂:

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

for循环中遍历$@的技巧:

"$@"数组是特殊的。如果要在for循环中遍历"$@",则可以缩写为

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

 for variable_name; do 
 done

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

这也适用于仅posix shell (dash, bourne shell),这些shell没有数组变量,但支持"$@""$*

要遍历它们,可以使用双引号括起来的$@,如下所示:

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

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

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

废话废话

如果省略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奖"的愤怒。人群:-)

如果你在想:

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

cat是完全不必要的。你可以使用:

awk 'do something' "${fspec}"

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

相关内容

  • 没有找到相关文章

最新更新