您的位置:首页 > 运维架构 > Shell

shell字符串操作技巧

2015-12-22 17:49 387 查看
操作字符串
--------------
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一个假的输入,
#+ 这样可以不用提供一个文件名.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: