一、获取表达式的值
shell
获取表达式的值,通常可以使用反引号``。
示例如下:
cat 1.txt | while read line
do
pid=`echo $line | awk '{print $1}'`
dt=`echo $line | awk '{print $2,$3}'`
echo `clickhouse-client --multiline -h ip --port port --database database --query="select count(*), sum(money), count(distinct open_id) from v_match_base_fix_table_8kw where pid='$pid' and dt <='$dt';"` $pid>>2.txt
done
读取文档1.txt
,并分开获取第一列和二三列的值,作为参数传给sql
语句,再将sql查询的结果值和pid的值保存在文档2.txt
二、条件判断表达式
2.1、if的基本语法:
if [ condition ]&&[ condition ]&&[ condition ]; then
command
elif [ condition ]; then
command
else
command
fi
2.2、文件/文件夹判断
[ -b FILE ] 如果 FILE 存在且是一个块特殊文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字特殊文件则为真。
[ -d DIR ] 如果 FILE 存在且是一个目录则为真。
[ -e FILE ] 如果 FILE 存在则为真。
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -p FILE ] 如果 FILE 存在且是一个名字管道(F如果O)则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -w FILE ] 如果 FILE存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -N FILE ] 如果 FILE 存在 and has been mod如果ied since it was last read则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字则为真。
[ FILE1 -nt FILE2 ] 如果 FILE1 has been changed more recently than FILE2, or 如果 FILE1 exists and FILE2 does not则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 要老, 或者 FILE2 存在且 FILE1 不存在则为真。 [ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真。
2.3、字符串判断
[ -z STRING ] 如果STRING的长度为零则为真 ,即判断是否为空,空即是真;
[ -n STRING ] 如果STRING的长度非零则为真 ,即判断是否为非空,非空即是真;
[ STRING1 = STRING2 ] 如果两个字符串相同则为真 ;
[ STRING1 != STRING2 ] 如果字符串不相同则为真 ;
[ STRING1 ] 如果字符串不为空则为真,与-n类似
2.4、数值判断
INT1 -eq INT2 INT1和INT2两数相等为真 ,=
INT1 -ne INT2 INT1和INT2两数不等为真 ,<>
INT1 -gt INT2 INT1大于INT1为真 ,>
INT1 -ge INT2 INT1大于等于INT2为真,>=
INT1 -lt INT2 INT1小于INT2为真 ,<</div>
INT1 -le INT2 INT1小于等于INT2为真,<=
2.5、复杂逻辑判断
# -a 与 &&
# -o 或 ||
# ! 非
2.6、示例
if [ "$stimes" -ge "100" ]&&[ "$money" -ge "10000" ]&& [ "$people" -ge "50" ]; then
echo $pid >>success.txt
else
echo $pid >>failed.txt
fi
shell if [[]]和[]区别 || &&
[]和test
两者是一样的,在命令行里test expr
和[ expr ]
的效果相同。test的三个基本作用是判断文件、判断字符串、判断整数。支持使用"与或非"将表达式连接起来。test
中可用的比较运算符只有==
和!=
,两者都是永远字符串比较的,补课用于整数比较,整数毕竟只能使用-eq
,-gt
这种形式。无论是字符串比较还是整数比较都千万不要使用大于号小于号。当然,如果你实在想用也是可以的,对应字符串毕竟可以使用尖括号的转义形式,如果比较"ab"
和"bc"
:[ ac \< bc ]
,结果为真,也就是返回状态0
。
[[]]
这是内置在shell
中的一个命令,它就比刚才说的test
强大的多了。支持字符串的模式匹配(使用=~
操作符时甚至支持shell
的正则表达式)。逻辑组合可以不使用test
的-a
,-o
而使用&&
,||
。字符串比较时可以把右边的作为一个模式(这是右边的字符串不加双引号的情况下。如果右边的字符串加了双引号,则认为是一个文字符串),而不仅仅是一个字符串,比如[[ hello == hell? ]]
,结果为真。
注意:使用[ ]
和[[ ]]
的时候不要吝啬空格,每一项两边都要有空格,[[ 1 == 2 ]]
的结果为"假",但[[ 1==2 ]]
的结果为"真"!
let和(())
两者也是一样的(或者说基本上是一样的,双括号比let
稍弱一些)。主要进行算术运算(上面的两个都不行),也比较适合进行整数比较,可以直接使用熟悉的<
,>
等比较运算符。可以直接使用变量名如var
而不需要$var
这样的形势。支持分号隔开的多个表达式
#################################################################################
-
首先,尽管很相似,但是从概念上讲,二者是不同层次的东西。
[[
,是关键字,许多shell
(如ash
,bsh
)并不支持这种方式。ksh
,bash
(据说从2.02起引入对[[
的支持)等支持。 -
[[ ]]
结构比bash版本的[ ]
更通用。在[[
和]]
之间的所有字符都不会被文件扩展或是标记分割,但是会有参数引用和命令替换。用[[ ... ]]
测试结构比用[ ... ]
更能防止脚本里的许多逻辑错误。比如说,&&
,||
,<
和>
操作符能在一个[[ ]]
测试里通过,但在[ ]
结构会发生错误。 -
(( ))
结构扩展并计算一个算术表达式的值。如果表达式值为0
,会返回1
或假作为退出状态码。一个非零值的表达式返回一个0
或真作为退出状态码。这个结构和先前test
命令及[ ]
结构的讨论刚好相反。 -
[[ ... ]]
为shell命令,所以在其中的表达式应是它的命令行参数,所以字符串比较操作符>
与<
必须转义,否则就变成IO
改向操作符了。在[[
中<
与>
不需要转义。 -
[[ ... ]]
进行算术扩展,而[ ... ]
不做 -
[[ ... && ... && ... ]]
和[ ... -a ... -a ... ]
不一样,[[ ]]
是逻辑短路操作,而[ ]
不会进行逻辑锻炼
在ksh中的test
数字的运算可使用let、(( )),其中运算时不需要变量$符号,运算符为+、-、*、/、%,不建议使用expr