bash基础内置命令:
- echo
- eval
- exec
- export
- read
- shift
echo
- -n
不换行输出
- -e
解析字符串中的特殊符号
- \n
换行
- \r
回车
- \t
制表符(四个空格)
- \b
退格
实例:
[lidapeng@X61s ~]$ echo abc
abc
[lidapeng@X61s ~]$ echo abc;echo efs
abc
efs
[lidapeng@X61s ~]$ echo -n abc;echo efs
abcefs
[lidapeng@X61s ~]$ echo -n abc;echo -n efs
abcefs[lidapeng@X61s ~]$
[lidapeng@X61s ~]$ echo "wkn\nabc"
wkn\nabc
[lidapeng@X61s ~]$ echo -e "wkn\nabc"
wkn
abc
[lidapeng@X61s ~]$ printf "你好\t我是"
你好 我是[lidapeng@X61s ~]$ printf "你好\t我是\n"
你好 我是
eval
执行多个命令,将后面的内容作为参数传给它进行执行,每个命令之间以分号分隔:
eval ls;cd /tmp
exec
不创建子进程执行后续命令,且执行完毕后执行exit退出当前shell。
shell子串
- ${变量}
返回变量值
- ${#变量}
返回变量长度,字符串长度
- ${变量:start}
返回变量start数值之后的字符
[lidapeng@X61s /tmp]$ a=1234567890
[lidapeng@X61s /tmp]$ echo ${a:2}
34567890
- ${变量:start:length}
提取start之后的length限制的字符
[lidapeng@X61s /tmp]$ echo ${a:2:4}
3456
[lidapeng@X61s /tmp]$ echo ${a::4}
1234
[lidapeng@X61s /tmp]$ echo ${a:${#a}-2:4} 使用${#a}获取长度,然后从长度-2之后(即从8后面)开始截取,截取4个,实际获取到最后两个字符。
90
[lidapeng@X61s /tmp]$ echo ${a:${#a}-6:4} 使用${#a}获取长度,然后从长度-6之后(即从4后面)开始截取,截取4个。
5678
- ${变量#word}
从变量开头删除最短匹配的word子串
[lidapeng@X61s /tmp]$ echo ${a#1234}
567890
- ${变量##word}
从变量开头删除最长匹配的word
- ${变量%word}
从变量结尾删除最短的word
- ${变量%%word}
从变量结尾开始删除最长匹配的word
- ${变量/pattern/string}
用string替换第一个匹配的pattern
- ${变量//pattern/string}
用string替换所有匹配的pattern
计算变量长度的命令:
- echo ${#变量}
最快
- echo ${变量} | wc -L
wc -l统计行数(空行也算),-L统计最长那一行中元素的个数
- expr length "${a}"
freebsd中的expr好像不是这样用的
- echo ${变量} | awk '{print length($0)}'
for num in {1..100};do echo $num;done
三种统计长度方式对比(使用管道符一般都会慢):
[lidapeng@X61s ~]$ for n in {1..3};do str1=`seq -s ":" 10`;echo $str1;done seq -s ":" 10 命令生成一个从1到10,以分号分隔的数列
1:2:3:4:5:6:7:8:9:10:
1:2:3:4:5:6:7:8:9:10:
1:2:3:4:5:6:7:8:9:10:
[lidapeng@X61s ~]$ time for n in {1..10000};do char=`seq -s "abc" 100`;echo ${#char} &>/dev/null;done
real 0m27.419s 实际运行的时间
user 0m8.886s 用户态执行的时间
sys 0m19.499s 内核态执行的时间
[lidapeng@X61s ~]$ time for n in {1..10000};do char=`seq -s "abc" 100`;echo ${char}|wc -L &>/dev/null;done
real 1m8.847s
user 0m22.304s
sys 0m58.635s
[lidapeng@X61s ~]$ time for n in {1..10000};do char=`seq -s "abc" 100`;echo ${char}|awk '{print length($0)}' &>/dev/null;done
real 1m6.178s
user 0m21.370s
sys 0m56.995s
shell编程尽量使用linux内置的命令、内置的操作、内置的函数、尽可能减少管道符操作
截取字符串
[lidapeng@X61s ~]$ name2="abcABC123ABCabc"
[lidapeng@X61s ~]$ echo ${name2#a*c}
ABC123ABCabc
[lidapeng@X61s ~]$ echo ${name2##a*c}
[lidapeng@X61s ~]$ echo ${name2##a*b}
c
[lidapeng@X61s ~]$ echo ${name2##a*B}
Cabc
[lidapeng@X61s ~]$ echo ${name2#a*B}
C123ABCabc
[lidapeng@X61s ~]$
[lidapeng@X61s ~]$ echo $name2
abcABC123ABCabc
[lidapeng@X61s ~]$ echo ${name2%a*c}
abcABC123ABC
[lidapeng@X61s ~]$ echo ${name2%%a*c}
[lidapeng@X61s ~]$
替换字符串
[lidapeng@X61s ~]$ str1="Hello,man,i am your brother."
[lidapeng@X61s ~]$ echo $str1
Hello,man,i am your brother.
[lidapeng@X61s ~]$ echo ${str1/man/boy}
Hello,boy,i am your brother.
[lidapeng@X61s ~]$ echo ${str1/o/O}
HellO,man,i am your brother.
[lidapeng@X61s ~]$ echo ${str1//o/O}
HellO,man,i am yOur brOther.
批量修改文件名的案例
[lidapeng@X61s ~/sub_str]$ touch lidapeng_{1..5}_finished.jpg
[lidapeng@X61s ~/sub_str]$ touch lidapeng_{1..5}_finished.png
[lidapeng@X61s ~/sub_str]$ ls
lidapeng_1_finished.jpg lidapeng_2_finished.jpg lidapeng_3_finished.jpg lidapeng_4_finished.jpg lidapeng_5_finished.jpg
lidapeng_1_finished.png lidapeng_2_finished.png lidapeng_3_finished.png lidapeng_4_finished.png lidapeng_5_finished.png
以上准备数据源
[lidapeng@X61s ~/sub_str]$ f=lidapeng_1_finished.jpg
[lidapeng@X61s ~/sub_str]$ echo $f
lidapeng_1_finished.jpg
[lidapeng@X61s ~/sub_str]$ echo ${f//_finished/}
lidapeng_1.jpg
以上利用变量的子串功能去掉需要的字符
[lidapeng@X61s ~/sub_str]$ mv $f `echo ${f//_finished/}`
[lidapeng@X61s ~/sub_str]$ ls
lidapeng_1_finished.png lidapeng_2_finished.jpg lidapeng_3_finished.jpg lidapeng_4_finished.jpg lidapeng_5_finished.jpg
lidapeng_1.jpg lidapeng_2_finished.png lidapeng_3_finished.png lidapeng_4_finished.png lidapeng_5_finished.png
以上利用反引号功能调用系统命令返回值来修改单个文件名
[lidapeng@X61s ~/sub_str]$ ls *fin*.jpg
lidapeng_2_finished.jpg lidapeng_3_finished.jpg lidapeng_4_finished.jpg lidapeng_5_finished.jpg
[lidapeng@X61s ~/sub_str]$ for file_name in `ls *fin*.jpg` ; do echo $file_name;done
lidapeng_2_finished.jpg
lidapeng_3_finished.jpg
lidapeng_4_finished.jpg
lidapeng_5_finished.jpg
以上使用循环依次列出要找的文件名
[lidapeng@X61s ~/sub_str]$ for file_name in `ls *fin*.jpg` ; do mv $file_name `echo ${file_name//_finished/}`;done
[lidapeng@X61s ~/sub_str]$ ls *.jpg
lidapeng_1.jpg lidapeng_2.jpg lidapeng_3.jpg lidapeng_4.jpg lidapeng_5.jpg
以上使用循环修改文件名