shell子串
bash一些基础的内置命令
echo
eval
exec
export
read
shift
echo的输出用法
-n 不换行
-e 解析字符串中的特殊符号
\n 换行
\r 回车
\t 制表符 四个空格
\b 退格
1. ; 号用于换行输出
[root@localhost ~]# echo 你好呀;echo 见到你我很开心
你好呀
见到你我很开心
2. -n 命令取消换行
[root@localhost ~]# echo -n 你好要;echo 见到你我很开心
你好要见到你我很开心
[root@localhost ~]# echo -n 你好要;echo -n 见到你我很开心
你好要见到你我很开心[root@localhost ~]#
3. -e 识别特殊符号
[root@localhost ~]# echo -e "我看你今天心情很\n开心"
我看你今天心情很
开心
printf 打印命令
printf 打印命令 \t 相当于tab
[root@localhost ~]# printf "你好\t我是\t吴彦祖\n"
你好 我是 吴彦祖
eval 执行多个命令(;号分割每一个命令)
[root@localhost ~]# eval ls;cd /tmp
anaconda-ks.cfg getflower getpawer
t
fx.sh getflower1 mysql57-community-release-el7-11.noarch.rpm text
getday getflower2 shell1
exec 不创建子进程,执行后续命令,且执行完毕后,自动exit
[root@localhost tmp]# exec date
Mon Apr 8 15:00:52 CST 2024
──────────────────────────────────────────────────────────
Session stopped
shell子串的花式用法
1.学习基础语法
${变量} 返回变量值
${#变量} 返回变量长度,字符长度
${变量:start} 返回变量offset数值之后的字符
${变量:start:lenght} 提取offset之后的length限制的字符
${变量#word} 从变量开头删除最短匹配的word子串
${变量##word} 从变量开头删除最长匹配的word子串
${变量%word} 从变量结尾删除最短匹配的word子串
${变量%%word} 从变量结尾删除最长匹配的word子串
${变量/pattern/string} 用string代替第一个匹配的pattern
${变量//pattern/string} 用string代替所有的pattern
子串的实际案例
1.截取字符串(分割字符串内容)
[root@localhost ~]# name="hellolihao"
[root@localhost ~]# echo ${name:5}
lihao
1.1 指定起点,并设置截取长度
[root@localhost ~]# echo ${name:5:2}
li
2.计算变量长度
1)小写的l是统计变量的行数,大写的L是统计行内元素最长的元素的个数
[root@localhost ~]# echo $name | wc -l
1
[root@localhost ~]# echo $name | wc -L
10
2)WC在文本中的应用
[root@localhost ~]# cat text_wc.txt
123
12345
1234567
[root@localhost ~]# cat text_wc.txt |wc -l
3
[root@localhost ~]# cat text_wc.txt |wc -L
7
3)expr来计算字符串的长度
[root@localhost ~]# name="hellolihao"
[root@localhost ~]# expr length "${name}"
10
4)awk 函数统计字符串的长度 其中$o是取一整行变量
[root@localhost ~]# echo "${name}" | awk '{print length($0)}'
10
5)最快的统计方式
[root@localhost ~]# echo ${#name}
10
字符串长度统计方法这么多,谁最快?
需要用到一下知识来验证
- time命令,用于统计执行时长
- for循环的shell编程知识
语法:
for number in {1…100}
do
echo $number
done
写在一行的方法
for num in {1…100} ; do echo $num ; done
1. seq 生成序列的命令(默认分割符是空格)
[root@localhost ~]# seq 10
1
2
3
4
5
6
7
8
9
10
2) 自定义分割符,且指定生成的序列个数
[root@localhost ~]# seq -s ":" 10
1:2:3:4:5:6:7:8:9:10
开始检验测试统计时间
1. ${变量#word}的统计速度测试如下,计算时间为0.753s
[root@localhost ~]# time for n in {1..1000};do char=`seq -s "fgf" 100`;echo ${#char} &>/dev/null ; done
real 0m0.753s 实际运行的时间
user 0m0.523s 用户态执行的时间
sys 0m0.238s 内核态执行的时间
2. wc加管道符,用时1.787s
[root@localhost ~]# time for n in {1..1000};do char=`seq -s "fgf" 100`;echo ${char}|wc -L &>/dev/null ; done
real 0m1.787s
user 0m1.487s
sys 0m0.695s
3. expr length 函数统计,用时1.339s
[root@localhost ~]# time for n in {1..1000};do char=`seq -s "fgf" 100`;expr length "${char}" &>/dev/null ; done
real 0m1.339s
user 0m1.039s
sys 0m0.368s
4. awk 统计方法,用时1.606s
[root@localhost ~]# time for n in {1..1000};do char=`seq -s "fgf" 100`;echo ${char}|awk '{print length($0)}' &>/dev/null ; done
real 0m1.606s
user 0m1.512s
sys 0m0.557s
由验证结果显示,${#name}效率最高,shell编程,尽量使用Linux内置的命令,内置的操作,和内置的函数,效率最高c语言开发,效率最高,尽可能的减少管道符的操作。
字符串的截取
实际练习
1 删除匹配到的字符串
1. 通配符辅助删除,一个#号表示从开头删除符合a*c的最短字符串,两个#号表示从开头删除符合a*c的最长字符串
[root@localhost ~]# name2="abcABC123ABCabc"
[root@localhost ~]# echo ${name2#a*c}
ABC123ABCabc
[root@localhost ~]# echo ${name2##a*c}
[root@localhost ~]#
2. %号从变量的结尾删除
[root@localhost ~]# echo ${name2%a*c}
abcABC123ABC
[root@localhost ~]# echo ${name2%%a*c}
[root@localhost ~]#
如果通配符在变量中没有找到符合要求的,则原样输出!
替换字符串
[root@localhost ~]# str1="Hello,man,I am your brother"
[root@localhost ~]# echo ${str1/man/boy}
Hello,boy,I am your brother
一个斜杠/只会把符合要求的第一个单词给替换到,两个//斜杠才会将变量全文替换。
[root@localhost ~]# echo ${str1/o/O}
HellO,man,I am your brother
[root@localhost ~]# echo ${str1//o/O}
HellO,man,I am yOur brOther
删除文件名的案例:
准备数据源:
1. 批量创建文件
[root@localhost sub_str]# touch file_{1..5}_finished.jpg
[root@localhost sub_str]# touch file_{1..5}_finished.png
[root@localhost sub_str]# ls -l
total 0
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_1_finished.jpg
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_1_finished.png
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_2_finished.jpg
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_2_finished.png
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_3_finished.jpg
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_3_finished.png
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_4_finished.jpg
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_4_finished.png
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_5_finished.jpg
-rw-r--r--. 1 root root 0 Apr 8 16:40 file_5_finished.png
问题1去掉文件名的__finished 字符串信息去掉
思路1:手动一个一个的去掉
mv file_1_finished.jpg file_1.jpg
思路2:利用变量子串的功能,去掉字符信息
f=file_1_finished.jpg
echo ${f//_finished/} # 找出_finished的并替换为空
思路3:利用反引号的功能,修改文件名,结合了思路1和思路2
[root@localhost sub_str]# f=file_1_finished.png
[root@localhost sub_str]# echo $f
file_1_finished.png
[root@localhost sub_str]# mv $f `echo ${f//_finished/}`
思路4:批量文件名替换,只修改所有的jpg文件,反引号会输出命令返回值
[root@localhost sub_str]# ls *fin*.jpg
file_1_finished.jpg file_3_finished.jpg file_5_finished.jpg
file_2_finished.jpg file_4_finished.jpg
循环打印出了反引号中的返回值
[root@localhost sub_str]# for file_name in `ls *fin*.jpg`;do echo $file_name;done
file_1_finished.jpg
file_2_finished.jpg
file_3_finished.jpg
file_4_finished.jpg
file_5_finished.jpg
开始操作:
[root@localhost sub_str]# for file_name in `ls *fin*.jpg`;do mv $file_name `echo ${file_name//_finished/}`;done
[root@localhost sub_str]# ls *jpg
file_1.jpg file_2.jpg file_3.jpg file_4.jpg file_5.jpg