Bash字符串的处理

# 定义几个变量用于测试目的
FILE_NAME="/usr/local/app/world.txt"
TIME_NOW="`date +"%Y%m%d%H%M%S"`"
1. 取字符串的子串, 比如说从TIME_NOW分别取出日期和时间
DATE_TODAY="${TIME_NOW:0:8}"    # ${var:beg_pos:sub_str_length}, beg_pos是子串的起始位置(从0开始), sub_str_length为子串长度
TIME_TODAY="${TIME_NOW:8:6}"
# 或者
TIME_TODAY="${TIME_NOW:8}"      # sub_str_length为0表示到源字符串的结尾
# 取FILE_NAME中的文件名world.txt(不包括路径), 很多童鞋会马上想到basename, 或者一些类似于正则匹配的操作
${FILE_NAME##*/}                # 相当于basename ${FILE_NAME},即删除按从左至右,匹配一直到最后一个/之间的子串
${FILE_NAME%/*}                 # 相当与dirname, 即删除按从右至左方向开始,匹配到第一个/之间的子串
${FILE_NAME#*/}                 # 从左至右, 删除第一个/及左边的子串
${FILE_NAME%%/*}                # 从右至左, 删除至最后一个/及右边的子串
2. 字符串替换
${FILE_NAME/world.txt/hello.txt}    # 把第一个world.txt替换成hello.txt
${FILE_NAME//a/A}                   # 把所有的a替换成A
%x=abcdabcd
%echo ${x/a/b} # 只替换一个
bbcdabcd
%echo ${x//a/b} # 替换所有
bbcdbbcd
3. 计算字符串长度
${#FILE_NAME}                   # 计算FILE_NAME的长度
ARRAY=(abc defg hijklmn)
${#ARRAY}                       # 计算这个数组的维数
${#ARRAY[2]}                    # 计算这个数组第三个元素的长度
4.basename是最常用的,除此之外,Bash中还有个用字符串处理的方法(适用于bash):
for i in /var/html/*
do
   echo $i #全路径名
   echo ${i##*/} #文件名
done

#表示去除从指定字符向前所有的字符;##表示最大匹配。

%表示去除从指定字符向后所有的字符;%%表示最大匹配。

单个的表示最小匹配,双个表示最大匹配。
也就是说,当匹配的有多种方案的时候,选择匹配的最大长度还是最小长度。

str="abbc,def,ghi,abcjkl"
echo ${str#a*c}     # 输出,def,ghi,abcjkl  一个井号(#) 表示从左边截取掉最短的匹配 (这里把abbc字串去掉)
echo ${str##a*c}    # 输出jkl,             两个井号(##) 表示从左边截取掉最长的匹配 (这里把abbc,def,ghi,abc字串去掉)
echo ${str#"a*c"}   # 输出abbc,def,ghi,abcjkl 因为str中没有"a*c"子串
echo ${str##"a*c"}  # 输出abbc,def,ghi,abcjkl 同理
echo ${str#*a*c*}   # 空
echo ${str##*a*c*}  # 空
echo ${str#d*f)     # 输出abbc,def,ghi,abcjkl,
echo ${str#*d*f}    # 输出,ghi,abcjkl  
 
echo ${str%a*l}     # abbc,def,ghi  一个百分号(%)表示从右边截取最短的匹配
echo ${str%%b*l}    # a             两个百分号表示(%%)表示从右边截取最长的匹配
echo ${str%a*c}     # abbc,def,ghi,abcjkl
 可以这样记忆, 井号(#)通常用于表示一个数字,它是放在前面的;百分号(%)卸载数字的后面; 或者这样记忆,在键盘布局中,井号(#)总是位于百分号(%)的左边(即前面)
5.去掉扩展名,匹配语句

for i in /var/html/*
do
   echo $i #全路径名
   filename=${i##*/} #带扩展名的文件名,用basename也可以
   echo ${filename%.*} #去除扩展名的文件名
done
或者用sed的正则替换命令:

for i in /var/html/*
do
   echo $i #全路径名
   echo $i|sed -r 's#.*/(.*)..*#1#' #去除扩展名的文件名
done
 或者用awk:

for i in /var/html/*
do
   echo $i #全路径名
   echo $i|awk -F"[/.]" '{print $(NF-1)}' #去除扩展名的文件名
done

原文地址:https://www.cnblogs.com/Rainbow-G/p/4080035.html