shell expr match

expr match "$pwrdm_stat" ".*,($pwr_state:[0-9]*)" 不理解

从字符串开始的位置匹配子串的长度

  expr match "$string" '$substring' $substring是一个正则表达式
  expr "$string" : '$substring'  $substring是一个正则表达式
 
expr match "$string" '($substring)'
从$string的开始位置提取$substring,$substring是一个正则表达式.  
expr "$string" : '($substring)'
从$string的开始位置提取$substring,$substring是一个正则表达式.
stringZ=abcABC123ABCabc  
    echo `expr match "$stringZ" '(.[b-c]*[A-Z]..[0-9])'`   # abcABC1
    echo `expr "$stringZ" : '(.[b-c]*[A-Z]..[0-9])'`     # abcABC1
    echo `expr "$stringZ" : '(.......)'`           # abcABC1
 
所以:
expr match "$pwrdm_stat" ".*,($pwr_state:[0-9]*)"
. 代表一定有一个任意字符
* 代表重复零到无穷多个前一个字符
 
pwr_state=xx
# expr match "1233,xx:99xxx" ".*,($pwr_state:[0-9]*)"
.*, 一个任意字符 重复零到无穷多个前一个字符(重复3次任意字符) 外加一个逗号,
提取xx:[0-9]* 表示xx:后跟0-9任意一个数字,*表示重复零到无穷多个前一个字符
 输出结果为:xx:99

 
 
转自 https://www.cnblogs.com/tychyg/p/5067453.html 备用

shell字符串操作技巧

操作字符串
--------------
Bash支持超多的字符串操作,操作的种类和数量令人惊异.但不幸的是,这些工具缺乏集中性.
一些是参数替换的子集,但是另一些则属于UNIX的expr命令.这就导致了命令语法的不一致和
功能的重叠,当然也会引起混乱.
 
1、字符串长度
  ${#string}
  expr length $string
  expr "$string" : '.*'
   
  stringZ=abcABC123ABCabc
   
  echo ${#stringZ}                
  echo `expr length $stringZ`     
  echo `expr "$stringZ" : '.*'`   
 
2、从字符串开始的位置匹配子串的长度
  expr match "$string" '$substring' $substring是一个正则表达式
  expr "$string" : '$substring'  $substring是一个正则表达式
   
  stringZ=abcABC123ABCabc
  echo `expr match "$stringZ" 'abc[A-Z]*.2'`  
  echo `expr "$stringZ" : 'abc[A-Z]*.2'`      
3、索引
    expr index $string $substring 匹配到子串的第一个字符的位置.
    stringZ=abcABC123ABCabc
    echo `expr index "$stringZ" C12`            
 
    echo `expr index "$stringZ" 1c`             
    # 'c' (in #3 position) matches before '1'.
 
    在C语言中最近的等价函数为strchr().
提取子串
        ${string:position}
        在string中从位置$position开始提取子串.
        如果$string为"*""@",那么将提取从位置$position开始的位置参数,[1]
    ${string:position:length}
        在string中从位置$position开始提取$length长度的子串.
 
################################StartScript######################################
stringZ=abcABC123ABCabc
#       0123456789.....
#       0-based indexing.
 
echo ${stringZ:0}                            # abcABC123ABCabc
echo ${stringZ:1}                            # bcABC123ABCabc
echo ${stringZ:7}                            # 23ABCabc
echo ${stringZ:7:3}                          # 23A
                                             # 3个字符长度的子串.
# 有没有可能从字符结尾开始,反向提取子串?
     
echo ${stringZ:-4}                           # abcABC123ABCabc
# 以${parameter:-default}方式,默认是提取完整地字符串.
# 然而 . . .
echo ${stringZ:(-4)}                         # Cabc
echo ${stringZ: -4}                          # Cabc
# 现在,它可以工作了.
# 使用圆括号或者添加一个空格来转义这个位置参数.
 
如果$string参数为"*""@",那将最大的提取从$position开始的$length个位置参数.
 
    echo ${*:2}          # Echo出第2个和后边所有的位置参数.
    echo ${@:2}          # 与前边相同.
    echo ${*:2:3}        # 从第2个开始,Echo出后边3个位置参数.
    expr substr $string $position $length
        在string中从位置$position开始提取$length长度的子串.
    stringZ=abcABC123ABCabc
    #       123456789......
    #       1-based indexing.
     
    echo `expr substr $stringZ 1 2`              # ab
    echo `expr substr $stringZ 4 3`              # ABC
     
    expr match "$string" '($substring)'
        从$string的开始位置提取$substring,$substring是一个正则表达式.
     
    expr "$string" : '($substring)'
        从$string的开始位置提取$substring,$substring是一个正则表达式.
    stringZ=abcABC123ABCabc
     
    echo `expr match "$stringZ" '(.[b-c]*[A-Z]..[0-9])'`   # abcABC1
    echo `expr "$stringZ" : '(.[b-c]*[A-Z]..[0-9])'`       # abcABC1
    echo `expr "$stringZ" : '(.......)'`                   # abcABC1
    # All of the above forms give an identical result.
子串削除
    ${string#substring}
         从$string的左边截掉第一个匹配的$substring
    ${string##substring}
         从$string的左边截掉最后一个个匹配的$substring
    stringZ=abcABC123ABCabc
    #       |----|
    #       |----------|
     
    echo ${stringZ#a*C}      # 123ABCabc
    # 截掉'a''C'之间最近的匹配.
     
    echo ${stringZ##a*C}     # abc
    # 截掉'a''C'之间最远的匹配.
         
     
    ${string%substring}
         从$string的右边截掉第一个匹配的$substring
    ${string%%substring}
         从$string的右边截掉最后一个匹配的$substring
 
    stringZ=abcABC123ABCabc
    #                    ||
    #        |------------|
     
    echo ${stringZ%b*c}      # abcABC123ABCa
    # 从$stringZ的后边开始截掉'b''c'之间的最近的匹配
     
    echo ${stringZ%%b*c}     # a
    # 从$stringZ的后边开始截掉'b''c'之间的最远的匹配
 
Example 9-11 利用修改文件名,来转换图片格式
################################StartScript######################################
 #!/bin/bash
 #  cvt.sh:
 #  把一个目录下的所有MacPaint格式的图片文件都转换为"pbm"格式的图片文件.
  
 #  使用来自"netpbm"包的"macptopbm"程序,
 #+ 这个程序主要是由Brian Henderson(bryanh@giraffe-data.com)来维护的.
 #  Netpbm是大多数Linux发行版的标准部分.
  
 OPERATION=macptopbm
 SUFFIX=pbm          # 新的文件名后缀
  
 if [ -n "$1" ]
 then
   directory=$1      # 如果目录名作为第1个参数给出...
 else
   directory=$PWD    # 否则使用当前的工作目录.
 fi 
    
 #  假设在目标目录中的所有文件都是MacPaint格式的图片文件,
 #+ 以".mac"为文件名的后缀.
  
 for file in $directory/*    # Filename globbing.
 do
   filename=${file%.*c}      #  去掉文件名的".mac"后缀
                             #+ ('.*c' matches everything
                             #+ ('.*c' 将匹配'.'和'c'之间的任何字符串).
 
   $OPERATION $file > "$filename.$SUFFIX"
                             # 转换为新的文件名.
   rm -f $file               # 转换完毕后删除原有的文件.
   echo "$filename.$SUFFIX"  # 从stdout输出反馈.
 done
  
 exit 0
  
 
 #  修改这个脚本,让他只转换以".mac"为后缀的文件.
################################EndScript#######################################
        一个简单的模拟getopt命令的办法就是使用子串提取结构.
Example 9-12 模仿getopt命令
################################StartScript######################################
 #!/bin/bash
 # getopt-simple.sh
 # Author: Chris Morgan
 # 授权使用在ABS Guide中.
  
  
 getopt_simple()
 {
     echo "getopt_simple()"
     echo "Parameters are '$*'"
     until [ -z "$1" ]
     do
       echo "Processing parameter of: '$1'"
       if [ ${1:0:1} = '/' ]
       then
           tmp=${1:1}               # 去掉开头的'/' . . .
           parameter=${tmp%%=*}     # 提取名字.
           value=${tmp##*=}         # 提取值.
           echo "Parameter: '$parameter', value: '$value'"
           eval $parameter=$value
       fi
       shift
     done
 }
  
 # 传递所有的选项到getopt_simple().
 getopt_simple $*
  
 echo "test is '$test'"
 echo "test2 is '$test2'"
  
 exit 0
  
 ---
  
 sh getopt_example.sh /test=value1 /test2=value2
  
 Parameters are '/test=value1 /test2=value2'
 Processing parameter of: '/test=value1'
 Parameter: 'test', value: 'value1'
 Processing parameter of: '/test2=value2'
 Parameter: 'test2', value: 'value2'
 test is 'value1'
 test2 is 'value2'
################################EndScript#######################################
子串替换
    ${string/substring/replacement}
        使用$replacement来替换第一个匹配的$substring.
    ${string//substring/replacement}
        使用$replacement来替换所有匹配的$substring.
 
    1 stringZ=abcABC123ABCabc
    2
    3 echo ${stringZ/abc/xyz}           # xyzABC123ABCabc
    4                                   # 用'xyz'来替换第一个匹配的'abc'.
    5
    6 echo ${stringZ//abc/xyz}          # xyzABC123ABCxyz
    7                                   # 用'xyz'来替换所有匹配的'abc'.
 
    ${string/#substring/replacement}
        如果$substring匹配$string的开头部分,那么就用$replacement来替换$substring.
    ${string/%substring/replacement}
        如果$substring匹配$string的结尾部分,那么就用$replacement来替换$substring.
    1 stringZ=abcABC123ABCabc
    2
    3 echo ${stringZ/#abc/XYZ}          # XYZABC123ABCabc
    4                                   # 用'XYZ'替换开头的'abc'
    5
    6 echo ${stringZ/%abc/XYZ}          # abcABC123ABCXYZ
    7                                   # 用'XYZ'替换结尾的'abc'
 
 
9.2.1 使用awk来操作字符串
~~~~~~~~~~~~~~~~~~~~~~~~~
Bash脚本也可以使用awk来操作字符串.
Example 9-13 提取字符串的一种可选的方法
################################StartScript######################################
 #!/bin/bash
 # substring-extraction.sh
  
 String=23skidoo1
 #      012345678    Bash
 #      123456789    awk
 # 注意,对于awk和Bash来说,它们使用的是不同的string索引系统:
 # Bash的第一个字符是从'0'开始记录的.
 # Awk的第一个字符是从'1'开始记录的.
  
 echo ${String:2:4} # 位置3 (0-1-2), 4 个字符长
                                          # skid
  
 # awk中等价于${string:pos:length}的命令是substr(string,pos,length).
 echo | awk '
 { print substr("'"${String}"'",3,4)      # skid
 }
 '
 #  使用一个空的"echo"通过管道给awk一个假的输入,
 #+ 这样可以不用提供一个文件名.
原文地址:https://www.cnblogs.com/idyllcheung/p/10280845.html