魏长东

weichangdong

sh字符串操作

// 数字或者数字组合(能够返回结果,即程序退出状态是0,说明属于这种类型,反之不然)
$ i=5;j=9423483247234;
$ echo $i | grep [0-9]*
5
$ echo $j | grep [0-9]*
9423483247234
$ echo $j | grep [0-9]* >/dev/null
$ echo $?
0
// 字符组合(小写字母、大写字母、两者的组合)
$ c="A"; d="fwefewjuew"; e="fewfEFWefwefe"
$ echo $c | grep [A-Z]
A
$ echo $d | grep "[a-z]*"
fwefewjuew
$ echo $e | grep "[a-zA-Z]*"
fewfEFWefwefe
// 字母和数字的组合
$ ic="432fwfwefeFWEwefwef"
$ echo $ic | grep "[0-9a-zA-Z]*"
432fwfwefeFWEwefwef
// 空格或者Tab键等
$ echo " " | grep " "
  
$ echo -e "\t" | grep "[[:space:]]" #[[:space:]]会同时匹配空格和TAB键
 
$ echo -e " \t" | grep "[[:space:]]"
 
$ echo -e "\t" | grep "<tab>" #<tab>为在键盘上按下TAB键,而不是字符<tab>
// 匹配邮件地址
$ echo "test2007@lzu.cn" | grep "[0-9a-zA-Z\.]*@[0-9a-zA-Z\.]"
test2007@lzu.cn
// 匹配URL地址(以http链接为例)
$ echo "http://news.lzu.edu.cn/article.jsp?newsid=10135" | grep "http://[0-9a-zA-Z\./=?]*"
http://news.lzu.edu.cn/article.jsp?newsid=10135

// 计算某个字符串的长度,即所有字符的个数[这计算方法是五花八门,择其优着而用之]
$ var="get the length of me"
$ echo ${var}     # 这里等同于$var
get the length of me
$ echo ${#var}
20
$ expr length "$var"
20
$ echo $var | awk '{printf("%d\n", length($0));}'
20
$ echo -n $var |  wc -c
20
// 计算某些指定一个字符或者多个字符的个数
$ echo $var | tr -cd g | wc -c
2
$ echo -n $var | sed -e 's/[^g]//g' | wc -c
2
$ echo -n $var | sed -e 's/[^gt]//g' | wc -c
5
// 如果要统计单词个数,更多相关信息见《shell编程之数值计算》之 _单词统计_ 实例。
$ echo $var | wc -w
5
$ echo "$var" | tr " " "\n" | grep get | uniq -c
1
$ echo "$var" | tr " " "\n" | grep get | wc -l

tr -d 可以删除字符串。  去除空格尤其好用。

 

//1. bash提供的数组数据结构,它是以数字为下标的,和C语言从0开始的下标一样
$ var="get the length of me"
$ var_arr=($var)    #这里把字符串var存放到字符串数组var_arr中了,默认以空格作为分割符
$ echo ${var_arr[0]} ${var_arr[1]} ${var_arr[2]} ${var_arr[3]} ${var_arr[4]}
get the length of me
$ echo ${var_arr[@]}    #这个就是整个字符串所有部分啦,这里可以用*代替@,下同
get the length of me
$ echo ${#var_arr[@]}    #记得上面求某个字符串的长度么,#操作符,如果想求某个数组元素的字符串长度,那么就把@换成下标吧
5
// 你也可以直接给某个数组元素赋值
$ var_arr[5]="new_element"
$ echo ${var_arr[5]}
6
$ echo ${var_arr[5]}
new_element
// bash里头实际上还提供了一种类似于“数组”的功能,即"for i in 用指定分割符分开的字符串" 的用法
// 即,你可以很方便的获取某个字符串的某个部分
$  for i in $var; do echo -n $i" "; done;
get the length of me 
 
//2. awk里头的数组,注意比较它和bash提供的数组的异同
// split把一行按照空格分割,存放到数组var_arr中,并返回数组的长度。注意:这里的第一个元素下标不是0,而是1
$ echo $var | awk '{printf("%d %s\n", split($0, var_arr, " "), var_arr[1]);}'
5 get
// 实际上,上面的操作很类似awk自身的行处理功能:awk默认把一行按照空格分割为多个域,并可以通过$1,$2,$3...来获取,$0表示整行
// 这里的NF是该行的域的总数,类似于上面数组的长度,它同样提供了一种通过“下标”访问某个字符串的功能
$ echo $var | awk '{printf("%d | %s %s %s %s %s | %s\n", NF, $1, $2, $3, $4, $5, $0);}'
5 | get the length of me | get the length of me
// awk的“数组”功能何止于此呢,看看它的for引用吧,注意,这个和bash里头的for不太一样,i不是元素本身,而是下标
$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",var_arr);}'
get the length of me 
$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",i);}'
1 2 3 4 5 
// awk还有更“厉害”的处理能力,它的下标可以不是数字,而可以是字符串,从而变成了“关联”数组,这种“关联”的作用在某些方便将让我们非常方便

// 按照位置取子串,比如从什么位置开始,取多少个字符
$ var="get the length of me"
$ echo ${var:0:3}
get
$ echo ${var:(-2)}   # 方向相反呢
me
$ echo `expr substr "$var" 5 3` #记得把$var引起来,否则expr会因为空格而解析错误
the
$ echo $var | awk '{printf("%s\n", substr($0, 9, 6))}'
length
 
// 匹配字符求子串
$ echo ${var%% *} #从右边开始计算,删除最左边的空格右边的所有字符
get 
$ echo ${var% *} #从右边开始计算,删除第一个空格右边的所有字符
get the length of
$ echo ${var##* }  #从左边开始计算,删除最右边的空格左边的所有字符
me
$ echo ${var#* }  #从左边开始计算,删除第一个空格左边的所有字符
the length of me
 
$ echo $var | awk '{printf("%s\n", $1);}' # awk把$var按照空格分开为多个变量,依次为$1,$2,$3,$4,$5
get
$ echo $var | awk '{printf("%s\n", $5);}'
me
 
$ echo $var | cut -d" " -f 5  #差点把cut这个小东西忘记啦,用起来和awk类似, -d指定分割符,如同awk用-F指定分割符一样,-f指定“域”,如同awk的$数字。
 
$ echo $var | sed 's/ [a-z]*//g'  #删除所有 空格+字母串 的字符串,所以get后面的全部被删除了
get
$ echo $var | sed 's/[a-z]* //g'
me
 
$ echo $var | tr " " "\n" | sed -n 1p #sed有按地址(行)打印(p)的功能,记得先用tr把空格换成行号
get
$ echo $var | tr " " "\n" | sed -n 5p
me
 
// tr也可以用来取子串哦,它也可以类似#和%来“拿掉”一些字符串来实现取子串
$ echo $var | tr -d " "
getthelengthofme

觉得很有用的 是字符串的替换

${string/substring/replacement} 使用$replacement来替换第一个匹配的$substring
${string//substring/replacement} 使用$replacement来替换所有匹配的$substring.
${string/#substring/replacement} 如果$substring匹配$string的开头部分, 那么就用$replacement来替换$substring.
${string/%substring/replacement}  如果$substring匹配$string的结尾部分, 那么就用$replacement来替换$substring.