${}
利用${ }还可针对不同的变数状态赋值(沒设定、空值、非空值):
- ${var-myvar} 假如$var沒有设定,則使用myvar作返回值,空值及非空值时不作处理
- ${var:-myvar} 假如$var沒有设定或为空值,則使用myvar作返回值,非空值时不作处理
- ${var+myvar} 假如$var設为空值或非空值,均使用myvar作返回值,沒设定时不作处理
- ${var:+myvar} 若$var为非空值,則使用myvar作返回值,沒设定及空值时不作处理
- ${var=myvar} 若$var沒设定,則使用myvar作返回值,同时将$var赋值为myvar,空值及非空值时不作处理
- ${var:=myvar} 若$var沒设定或为空值,則使用myvar作返回值,同时将$var 赋值为myvar,非空值时不作处理
- ${var?myvar} 若$var沒设定,則将myvar輸出至STDERR,空值及非空值时不作处理
- ${var:?myvar} 若$var没设定或为空值,则将myvar输出至STDERR,非空值时不作处理
使用频次比较高的用法为${var:+myvar},一般用在shell可选的参数中,例如:
param=
# equal to script.sh other_params
script.sh ${param:+"--param $param"} other_params
shell program
- $*引用所有参数, $#存放参数的个数, $0引用程序名, $i第i个参数
- 数学计算
$ var=1+1 error # error,"1+1"
$ let var+=1 | let "var+=1"
$ var=`expr $var + 1`
$ ((var+=1))
$ var=$[$var+1] #自己推荐使用这个哈
数组
a=(1 2 3 4 5) #() 数组
a[1] = 100 #赋值
echo ${#a[*]} #length
echo ${a[*]} #all element
c=(${a[@]:1:4}) #${数组名[@或*]:起始位置:长度} 切片原先数组
括号 () {}
() 为了在子shell中执行一组命令,可以用命令分隔符(即”,”)隔开每一个命令,并把所有的命令用圆括号()括起来。 {} 如果使用{}来代替(),那么相应的命令将在当前shell中作为一个整体被执行
字符串
| 表达式 | 含义 |
|----------------------------------+-------------------------------------------------------------------------------|
| ${#string} | $string的长度 |
| ${string:position} | 在$string中, 从位置$position开始提取子串 |
| ${string:position:length} | 在$string中, 从位置$position开始提取长度为$length的子串 |
| ${string#substring} | 从变量$string的开头, 删除最短匹配$substring的子串 |
| ${string##substring} | 从变量$string的开头, 删除最长匹配$substring的子串 |
| ${string%substring} | 从变量$string的结尾, 删除最短匹配$substring的子串 |
| ${string%%substring} | 从变量$string的结尾, 删除最长匹配$substring的子串 |
| ${string/substring/replacement} | 使用$replacement, 来代替第一个匹配的$substring |
| ${string//substring/replacement} | 使用$replacement, 代替所有匹配的$substring |
| ${string/#substring/replacement} | 如果$string的前缀匹配$substring, 那么就用$replacement来代替匹配到的$substring |
| ${string/%substring/replacement} | 如果$string的后缀匹配$substring, 那么就用$replacemen |
sed
- -e 连续执行多个编辑
sed -e "s:aa:bb:" -e "s:\d::" file
- -i 在源文件上进行替换
#如删除windows下文件的^M显示
sed -i 's/^M//g' filename
- ()表示分组,_1,_2引用,标准正则表达式使用()
#如根据路径取x.wav的文件名
sed "s:.*/\(.*\)\.wav:\1:"
grep
- -P perl形式的正则表达式
- -v 不匹配的项
- -H 显示文件名
- -f 从文件中取得模式
- -i 忽略大小写
cut(default tab)
#-d分割符, -f域
$ cut -d' ' -f2
tr
- 只接收标准输入
- tr set1 set2
- tr “ “ “\n” 将空格换成回车
- tr “a-z” “A-Z” 或者 tr [:lower:] [:upper:] 大小写转换
- tr -s “ “ 将多个空格替换为1个
- tr -d 删除, tr -cd ‘[a-z]’
- tr -sc ‘a-z’ ‘\n’, -c取不是’a-z’, 所以将不是a-z的字符替换为换行
find
- -L 包含链接文件,默认不查找链接文件
- -name 文件名
- -type (f d l)
- -mmin 最近修改时间
- -maxdepth
$ find -L . -name "*.sh" -type f
awk
- 以awk文件方式运行, -f
#!/bin/awk
{print $0}
awk -f strcat.awk if.sh
-
字符串连接 a (“” ”+”) b - print printf
{print $0}
{printf("%04d %s", NR, $0)}
- -v 可带输入变量
awk -v num=10 '{print num}'
- 关联数组
#!/bin/awk
#word count
BEGIN {
FS="[^a-zA-Z]"
}
{
for(i=1; i<=NF; i++)
words[tolower($i)]++;
}
END {
delete words[""]
for (x in words)
print x, words[x];
}
- getline close(在脚本中要两次读取同一文件时要close)
#将拼音级的抄本查表转换成音素级抄本
#!/bin/bash
if [ $# -ne 2 ]; then
echo "Usage: pinyin2phone.sh dict_file pinyin2phone"
exit -1
fi
dict=$1
awk -v phone_map=$2 \
'BEGIN {
while (getline < phone_map) {
t = "";
for (i=2; i<=NF; i++)
t = t " " $i;
map[$1] = t;
#print $1, t
}
close(phone_map) #此处也可以不写
}
{
line = $1;
for (i=2; i<=NF; i++)
line = line " " map[$i];
print line;
}
' $dict
- 字符串处理函数
gsub(r,s) 在整个$0中用s替代r
gsub(r,s,t) 在整个t中用s替代r
index(s,t) 返回s中字符串t的第一位置
length(s) 返回s长度
match(s,r) 测试s是否包含匹配r的字符串
split(s,a,fs) 在fs上将s分成序列a
sprint(fmt,exp) 返回经fmt格式化后的exp
sub(r,s) 用$0中最左边最长的子串代替s
substr(s,p) 返回字符串s中从p开始的后缀部分
substr(s,p,n) 返回字符串s中从p开始长度为n的后缀部分
#仅仅使用begin在shell中格式化字符串
awk x=10 'BEGIN{printf("S%04d", x)}'
awk 'BEGIN{print split("123#456#678", myarray, "#")}'
awk '{BEGIN {print match("ANCD", /d/)}'
- system,调用shell命令
#function system(expr) uses /bin/sh to execute expr and returns the exit status of the command expr.
#假设文件file中每一行均为文件名,cat所有文件
$ awk '{system("cat" " " $0)}' file
- 莫给NR,NF加$,经常犯这个错
- other example
# emulate cat.
{ print }
# emulate wc.
{ chars += length($0) + 1 # add one for the \n
words += NF
}
END{ print NR, words, chars }
BRE vs ERE
Basic vs Extended Regular Expressions In basic regular expressions the meta-characters ?, +, {, |, (, and ) lose their special meaning; instead use the backslashed versions \?, +, {, |, (, and )
- 注意与linux命令中通配符区分 其在命令中表示任意字符重复任意次
- grep sed awk均使用BRE,grep在-E选项时可使用ERE
- 所以sed “:./(.).wav:\1:”就比较好理解了
PREVIOUS自然语言处理