当前位置:K88软件开发文章中心网站服务器框架Shell → 文章内容

Shell 字符串操作

减小字体 增大字体 作者:佚名  来源:网上搜集  发布时间:2019-1-23 14:39:35

事情。正因为这样,所以产生了大量优秀的行编辑工具,诸如 grep,awk,sed 等。在“行内”(姑且这么说吧,就是处理单行,即字符串中不再包含行分割符)的字符串分割方面,cut 和 awk 提供了非常优越的“行内”(处理单行)处理能力。更方便地处理用分割符分割好的各个部分同样是用到分割符,但为了更方便的操作分割以后的字符串的各个部分,我们抽象了“数组”这么一个数据结构,从而让我们更加方便地通过下标来获取某个指定的部分。 bash 提供了这么一种数据结构,而优秀的 awk 也同样提供了它,我们这里将简单介绍它们的用法。范例:把字符串拆分成字符串数组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_elementBash 实际上还提供了一种类似于“数组”的功能,即 for i in,它可以很方便地获取某个字符串的各个部分,例如:$ for i in $var; do echo -n $i"_"; doneget_the_length_of_me_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 meawk 的“数组”功能何止于此呢,看看它的 for 引用吧,注意,这个和 Bash 里头的 for 不太一样,i 不是元素本身,而是下标:$ echo $var | awk '{split($0, var_arr, " "); for(i in var_arr) printf("%s ",var_arr[i]);}'of me get the length4 5 1 2 3另外,从上述结果可以看到,经过 for 处理后,整个结果没有按照原理的字符顺序排列,不过如果仅仅是迭代出所有元素这个同样很有意义。awk 还有更“厉害”的处理能力,它的下标可以不是数字,可以是字符串,从而变成了“关联”数组,这种“关联”在某些方面非常方便。比如,把某个文件中的某个系统调用名根据另外一个文件中的函数地址映射表替换成地址,可以这么实现:$ cat symbolsys_exitsys_readsys_close$ ls /boot/System.map*$ awk '{if(FILENAME ~ "System.map") map[$3]=$1; else {printf("%s\n", map[$1])}}' \ /boot/System.map-2.6.20-16-generic symbolc0129a80c0177310c0175d80另外,awk还支持用delete函数删除某个数组元素。如果某些场合有需要的话,别忘了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))}'lengthawk 把 $var 按照空格分开为多个变量,依次为 $1,$2,$3,$4,$5$ echo $var | awk '{printf("%s\n", $1);}'get$ echo $var | awk '{printf("%s\n", $5);}'me差点略掉cut小工具,它用起来和awk类似,-d指定分割符,如同awk用-F指定分割符一样;-f指定“域”,如同awk的$数字。$ echo $var | cut -d" " -f 5范例:匹配字符求子串用 Bash 内置支持求字串:$ echo ${var%% *} #从右边开始计算,删除最左边的空格右边的所有字符get$ echo ${var% *} #从右边开始计算,删除第一个空格右边的所有字符get the length of$ echo ${var##* } #从左边开始计算,删除最右边的空格左边的所有字符me$ echo ${var#* } #从左边开始计算,删除第一个空格左边的所有字符the length of me删除所有 空格+字母组合 的字符串:$ echo $var | sed 's/ [a-z]*//g'get$ echo $var | sed 's/[a-z]* //g'mesed 有按地址(行)打印(p)的功能,记得先用 tr 把空格换成行号:$ echo $var | tr " " "\n" | sed -n 1pget$ echo $var | tr " " "\n" | sed -n 5pmetr 也可以用来取子串,它可以类似#和 % 来“拿掉”一些字符串来实现取子串:$ echo $var | tr -d " "getthelengthofme$ echo $var | tr -cd "[a-z]" #把所有的空格都拿掉了,仅仅保留字母字符串,注意-c和-d的用法getthelengthofme说明:% 和#删除字符的方向不一样,前者在右,后者在左,%% 和 %, ## 和 # 的方向是前者是最大匹配,后者是最小匹配。(好的记忆方法见网中人的键盘记忆法:#,$,% 是键盘依次从左到右的三个键)tr 的 -c 选项是 complement 的缩写,即 invert,而 -d 选项是删除,tr -cd "[a-z]" 这样一来就变成保留所有的字母对于字符串的截取,实际上还有一些命令,如果 head,tail 等可以实现有意思的功能,可以截取某个字符串的前面、后面指定的行数或者字节数。例如:$ echo "abcdefghijk" | head -c 4abcd$ echo -n "abcdefghijk" | tail -c 4hijk查询子串子串查询包括:返回符合某个模式的子串本身返回子串在目标串中的位置准备:在进行下面的操作之前,请准备一个文件 test.txt,里头有内容 "consists of",用于下面的范例。范例:查询子串在目标串中的位置expr index貌似仅仅可以返回某个字符或者多个字符中第一个字符出现的位置$ var="get the length of me"$ expr index "$var" t3awk却能找出字串,ma

上一页  [1] [2] [3] [4] [5]  下一页


Shell 字符串操作