Skip to content Skip to main navigation Skip to footer

shell: 【每日一博】Shell 特殊用法续

1.函数中输出函数名: $FUNCNAME

注意该变量是一个数组,如果嵌套调用函数,那么最里层函数中的此变量会是按调用顺序排列的所有函数的数组,如:

function log() {
    echo ${FUNCNAME[@]}
}
function action() {
    log
}
action 

输出内容是:log action

如果只想获得当前函数的名称,直接输出即可: echo $
FUNCNAME

用途:日志函数或者函数名传递等。

参考: Bash 获取当前函数名

2.循环中的跳转: continue [n]

首先需要声明的是continue可用于子函数,跳转到父函数中的指定层次循环。如:

function son() {
	for z in 1 2 3; do
		if true; then
			echo $x,$y,$z
			continue 3
		fi
	done
}
function father() {
	for x in 1 2 3; do
		for y in 1 2 3; do
			son
		done
	done
}
father
 
  • n的值从1开始(不写默认为1,数字越大则层数越高,超过总循环层数时值为最大层数);
  • 以上代码中只有最上层”x>”会正常循环完,其余子层都在首轮跳出,此时n的最大值为3;
  • 若在son后加一个“&”使其在后台运行,此时continue能控制y、z两层,但不能跳转到x,即n的最大值为2。

3.uniq注意事项

Note: ‘uniq’ does not detect repeated lines unless they are adjacent.

该命令容易被忽略的一点是,它只会比较相邻的行而不会跨行比较,除非必要,否则最好先排序:

sort -u

4.变量间接引用(indirect expansion)

两种方法见如下代码:

a=1
b=a
echo ${!b}
eval echo $$b

参考: shell 间接变量引用的问题
Parameter Expansion

5.sed模式空间

以下4种用法,第一个会替换每一行的第一个小写a,第二与第四个则会替换所有小写a,第三个只会替换第一行的第一个小写a:

printf 'aaanaaa' | sed 's/a/A/'
printf 'aaanaaa' | sed 's/a/A/g'
printf 'aaanaaa' | sed ':a;N;$!ba;s/a/A/'
printf 'aaanaaa' | sed ':a;N;$!ba;s/a/A/g' 

但是如果原始数据只有一行,那么最后两种写法均不会生效,

因此最好的写法是只替换第一行的第一个字符: printf ‘aaanaaan’ | sed ‘1s/a/A/’

参考: 让sed只替换一次

6.条件表达式

( ! [[ '123' =~ ^[0-9]+$ || 1 -gt 0 ]] ) && echo 1 || echo 2
( ! [ 1 -eq 2 -o 1 -gt 0 ] ) && echo 1 || echo 2
[ ! 1 -eq 2 -o 1 -gt 0 ] && echo 1 || echo 2
! [ 1 -eq 2 -o 1 -gt 0 ] && echo 1 || echo 2 

注意:

  • 带正则表达式的条件语句必须要写在双中括号“[[]]”中;

注意:在[] 表达式中,常见的>,<需要加转义字符,表示字符串大小比较,以acill码 位置作为比较。 不直接支持<>运算符,还有逻辑运算符|| && 它需要用-a[and] –o[or]表示

注意:[[]] 运算符只是[]运算符的扩充。能够支持<,>符号运算不需要转义符,它还是以字符串比较大小。里面支持逻辑运算符:|| &&

  • 如果要对整个条件语句取反,最好是将“!”写在“[]”之外,并且尽量用“()”包围起来;
  • 以上第三种写法没有达到要求,第四行不推荐,推荐前两种写法;

不考虑对低版本bash和对sh的兼容的情况下,用[[]]是兼容性强,而且性能比较快,在做条件运算时候,可以使用该运算符。

7.to be continued

原文:http://my.oschina.net/cwalet/blog/402756

0 Comments

There are no comments yet

Leave a comment

Your email address will not be published.