对于一般的变量,有无双引号效果是一样的,如下所示:
$ sport="marathon"
$ echo $sport
marathon
$ echo "$sport"
marathon
那么,对于二般的变量,就有差别了,如下:
$ cat sports.txt
walking running swimming
singing drawing dancing
basketball volleyball soccer
$ sports=$(cat sports.txt)
$ echo $sports
walking running swimming singing drawing dancing basketball volleyball soccer
$ echo "$sports"
walking running swimming
singing drawing dancing
basketball volleyball soccer
如上sports变量加上了双引号,echo "$sports"是将其原封不动的,作为一个整体输出。
原封不动是指,sports.txt文件中内容格式是什么样子,输出就是什么样子的。作为一个整体输出,又如何理解呢,可结合下面的for循环看下,其中${item}多加了‘-z’,是为了标示输出次数。可见变量加上双引号,只输出了一次。
$ for item in $sports; do echo ${item}-z; done
walking-z
running-z
swimming-z
singing-z
drawing-z
dancing-z
basketball-z
volleyball-z
soccer-z
$ for item in "$sports"; do echo ${item}-z; done
walking running swimming singing drawing dancing basketball volleyball soccer-z
类似sports这样的变量,在for循环中,一般是为了分析其中的每一行,因为"$sports"形式,作为一个整体输出了,所以不能用。只剩下$sports这种形式了,貌似该形式又输出次数太多了,其实这和Bash中的IFS(Internal Field Separator)变量有关,此处对IFS不做展开说明了,只给出两种解决方法。
第一种,改变IFS,示例代码如下:
$ sports=$(cat sports.txt)
$ old_ifs="$IFS"
$ IFS=$'\n'
$ for item in $sports; do echo $item; done
walking running swimming
singing drawing dancing
basketball volleyball soccer
$ IFS="$old_ifs"
$ for item in $sports; do echo $item; done
walking
running
swimming
singing
drawing
dancing
basketball
volleyball
soccer
第二种,先格式化sports.txt文件,示例代码如下:
$ sed -i -r 's/[ \t]{1,}/,/g' sports.txt
$ cat sports.txt
walking,running,swimming
singing,drawing,dancing
basketball,volleyball,soccer
$ sports=$(cat sports.txt)
$ for item in $sports; do echo $item; done
walking,running,swimming
singing,drawing,dancing
basketball,volleyball,soccer
对于两者,个人比较推荐第二种方法,预先格式化要处理的文件,可以确保熟知文件格式。
对Bash编程中,变量是否要加双引号,稍作总结:
1. 若打印变量内容(或将该变量作为参数传递给一个函数/脚本),要使用双引号。
2. 若变量在for循环中使用,不要使用双引号(留意上面提到的两种方法)。
原文地址:http://blog.51cto.com/coveringindex/2131139