查看shell脚本过程中的一些用法小结

使用名为shellceshi.sh的脚本用来测试,后续的“代码部分”在没有特别指明时默认指shellceshi.sh的代码

一、eval用法

1、调用最后一个参数
代码(后续用相同格式表示代码):

echo "最后一个参数为"$(eval echo \$$#)""

运行(后续用相同格式表示终端)

$ ./shallceshi.sh a b c d
最后一个参数为d

如果想得到倒数第二个参数

echo "倒数第二个参数为"$(eval echo \$$[$#-1])""

$ ./shallceshi.sh a b c d
倒数第二个参数为c

2、可以定义函数

_set_var() {
echo ceshi
}
eval "$1(){ _set_var; }"  #定义名为输入参数1的函数
set_var

$ ./shallceshi.sh set_var
ceshi

二、shift用法

shift n 移除前n个参数,不加n则默认移除第一个参数,相当于shift 1,且移除的参数不再可用,原来的所有参数会前移

shift
echo $@

$ ./shallceshi.sh a b c d
b c d

使用\给函数传递多个参数的方法

func() {
while [ -n "$1" ]; do  #参数不空就继续运行
  echo "当前参数为$1"
  shift
 done
}
func\
 a\
 b\
 c\

$ ./shallceshi.sh
当前参数为a
当前参数为b
当前参数为c

三、for循环

for读取列表中的值

sss="1 2 3 4 5"
for a in $sss 6  #a依次取in后面的值
 do
  echo $a
 done

$ ./shallceshi.sh
1
2
3
4
5
6

过程中,默认使用空格、制表符、换行符作为数据分隔符,如果想使用其他符号作为分隔符,需要更改IFS的值。
例如:

b=1,2,3,4,5
for a in $b
 do
  echo $a
 done

此时运行结果为

$ ./shallceshi.sh
1,2,3,4,5

如果我们想输出为

$ ./shallceshi.sh
1
2
3
4
5

那么设置逗号为分隔符(IFS)就可以满足上述要求

oldIFS=IFS  #保留原IFS值
IFS=,
b=1,2,3,4,5
for a in $b
 do
  echo $a
 done
 IFS=oldIFS #IFS恢复为默认值

另外,可以使用类C循环体

for(( ; ; ))    #((这里的条件、变量计算直接按C来写,不用加$,语句可以全空))
do
#命令
done
四、unset用法

用来删除变量,值得注意的是shell脚本中,指令本身可以用作变量。

aaa="echo qwe"
bbb=asd
unset=$aaa
unset bbb
echo $unset $bbb

$ ./shallceshi.sh
echo qwe

如果想执行"echo qwe"语句的话,把第五行的echo换成eval即可。

五、source、export命令

运行脚本文件有2种方式:
(1) $./shellceshi.sh
(2) $source shellceshi.sh
第一种方法是新建一个子shell运行脚本,涉及的变量会在子shell运行结束之后消失。如果需要将变量传递给子系统,需要使用export指令,例如
shellceshi.sh代码

export aaa=hello
./shallceshi2.sh

shallceshi2.sh代码

echo $aaa

$ ./shallceshi.sh
hello

第2种方法是读出脚本语句到当前shell执行,故脚本变量会保留在当前shell。以下代码帮助理解:
shellceshi.sh代码

export aaa=hello
./shallceshi2.sh
echo $aaa

shellceshi2.sh代码

echo $aaa
aaa="hello world!"
echo $aaa

$ ./shallceshi.sh
hello
hello world!
hello

显然shellceshi2.sh对参数aaa的更改没有传递给shellceshi.sh脚本,如果需要实现传递,则将shellceshi.sh代码改为:

export aaa=hello
source shallceshi2.sh
echo $aaa

$ ./shallceshi.sh
hello
hello world!
hello world!

其他用法,
export -n 变量 表示取消将该变量传递给子系统
export -p 列出当前所有环境变量
export - -\可以用来传递多个变量(注意后续每行的\都不能少,- -可以省略不写)
shellceshi.sh代码

aaa=hello   #可以先赋值,也可以在传递时赋值
export --\
  aaa\
  bbb="hello2"
./shallceshi2.sh

shallceshi2.sh代码

echo $aaa
echo $bbb

$ ./shallceshi.sh
hello
hello2

六、#* 、##* 、%*、%%*的用法

(1) ${变量#*[符号]} 删除变量中第一次出现该符号的左边部分(包括该符号也会删除)
(2) ${变量##*[符号]} 删除变量中最后一次出现该符号的左边部分
(3) ${变量%[符号]*} 删除变量中最后一次出现该符号的右边部分
(4) ${变量%%[符号]*} 删除变量中第一次出现该符号的右边部分
(5) ${#变量} 计算变量字符长度

file="/dir1/dir2/dir3/my.file.txt"
echo $file
a="${file#*r}"
echo $a
b="${file##*r}"
echo $b
c="${file%.*}"
echo $c
d="${file%%i*}"
echo $d

$ ./shallceshi.sh
/dir1/dir2/dir3/my.file.txt
1/dir2/dir3/my.file.txt
3/my.file.txt
/dir1/dir2/dir3/my.file
/d

注:
1)、符号可以写为[1-9]表示出现任意1-9的数字时,[a-c]表示任意a-c字母,[1 c]表示1或者c。
2)、变量可以从参数获取,直接数字表示即可

其他用法:
(5)${变量#字符串}从变量左边最小匹配字符串并删除
${变量##字符串}从变量左边最大匹配字符串并删除
${变量%字符串}从变量右边最小匹配字符串并删除
${变量%%字符串}从变量右边最大匹配字符串并删除

sss=abcabcdabcdeabcdefabcdefg
echo $sss
ssss="${sss#b}"  #左起第一个字符不是b,故不能匹配到,不进行任何操作
echo $ssss
sss2="${sss#a*c}" #删除左起匹配到a......c的最小串
echo $sss2
sss3="${sss##a*c}" #删除左起匹配到a......c的最大串
echo $sss3
sss4="${sss%d*g}" #删除右起匹配到d......g的最小串
echo $sss4
sss5="${sss%%d*g}" #删除右起匹配到d......g的最大串
echo $sss5

$ ./shallceshi.sh
abcabcdabcdeabcdefabcdefg
abcabcdabcdeabcdefabcdefg
abcdabcdeabcdefabcdefg
defg
abcabcdabcdeabcdefabc
abcabc

(6)${变量:数字a:数字b}:在变量中提取第a个字符后的b个字符,第(a+1)个字符是提取的第一个字符:
(7)可以对变量里的字符串作替换:
${变量/被替换的字符/新字符} 仅替换第一个
${变量//被替换的字符/新字符} 替换所有字符

file="/dir1/dir2/dir3/my.file.txt"
echo $file
e=${file:3:4}
echo $e
f=${file/dir/path}
echo $f
g=${file//dir/path}
echo $g

$ ./shallceshi.sh
/dir1/dir2/dir3/my.file.txt
r1/d
/path1/dir2/dir3/my.file.txt
/path1/path2/path3/my.file.txt

七、数值运算方法

(1)let 计算式、[计算式] 、((计算式)) 计算一般的整数型表达式
(2)expr用法:`expr 计算式` 需要注意:计算式前后加反引号`,计算式符号和数值要用空格隔开,乘号*前需要去义符号\
有多个表达式时,取值为最后一个表达式的值,如:

a=100
b=$[a+3**3] #这里的**表示乘方
c=$((a/4))
let d=(a-1,a-2,a-3)
e=`expr $a + 2 \* 8`
echo -e "$b\n$c\n$d\n$e"  #加入-e之后可以使用\n来表示换行

$ ./shallceshi.sh
127
25
97
116

变量i自加1可以使用多种方法:

#第一种方法
i=$[$i+1]   #中括号里的$可以省略,写成i=$[i+1]
#第二种方法
i=$(($i+1))  #也可以写成i=$((i+1))
#第三种方法
let i+=1
#第四种方法
let i++
#第五种方法
i=`expr $i + 1`
#第六种方法
((i++))

(3)bc的用法,可以进行浮点运算、进制转换、高阶运算
a)浮点运算时设定小数精度,scale=小数位数
b)进制转换,obase=目标进制,ibase=当前进制
c)sqrt(被开方数)等高阶运算

a=100
echo "scale=3;100/8"|bc
f=`echo "scale=3;100/8"|bc` #如果需要赋值
echo f=$f
g=`echo "obase=10;ibase=2;$a"|bc` #二进制转十进制
echo $g
h=`echo "obase=2;ibase=10;$a"|bc` #十进制转二进制
echo $h
i=`echo "scale=1;sqrt($a)"|bc`
echo $i

$ ./shallceshi.sh
12.500
f=12.500
4
1100100
10.0

八、^ 的一种用法

[^A-Z]表示除了不包含大写字母,^取反;^[A-Z]表示以大写字母开头

var="${1//[^a-zA-Z]/_}"  #将输入参数1中的所有非字母转换成下划线
echo $var

$ ./shallceshi.sh ^^Da@da%sd\ a
__Da_da_sd_a

九、&& 、||的用法

(1) 命令1 && 命令2 只有当命令1为真时(返回值为0)才执行后面的命令2,多个&&串接时同理
(2) 命令1 || 命令2 只有当命令1为假时(返回值为非0)才执行后面的命令2,多个||串接时同理

a=true
b=false
[ "$a" == "true" ] && echo a is true
[ "$b" == "true" ] && echo b is true
[ "$a" == "true" ] || echo a is false
[ "$b" == "true" ] || echo b is false
[ "$a" == "true" ] && [ "$b" == "true" ] || echo pass

$ ./shallceshi.sh
a is true
b is false
pass

例如,判断一个输入是否为数字

read a
echo $a | grep -q '[^0-9]' && echo no || echo yes
十、grep的用法

语法:grep -选项 ‘搜索内容串’ 待搜索文件
-a 以文本文件方式搜索
-c 计算找到的符合行的次数
-i 忽略大小写
-n 顺便输出行号
-v 反向选择,即搜索没有该字符串的行
-q 不打印输出结果
-E 大写 ,搜索内容串支持正则
-r 搜索当前文件夹下所有文件
-l 只显示文件名称
例如,shallceshi.sh内容

a
ab
Abc
aBcd

hello
hello world

终端运行(由于要用引号只能用这种方式写了):

$ grep -c 'a' shallceshi.sh
3
$ grep 'a' shallceshi.sh -ci #选项也可以置于后面
4
$ grep 'a' shallceshi.sh -n
1:a
2:ab
4:aBcd
$ grep -v 'a' shallceshi.sh
Abc

hello
hello world

搜索字符可以使用[ ]表示搜索合集,表示含有其中某一个字符。例如[b-d]表示bcd三个字符中的一个,[3c]表示3或c;符号^在[ ]内部时表示取反,[^ad]表示除了a、d之外的符号

$ grep '[b-d]' shallceshi.sh
ab
Abc
aBcd
hello world
$ grep '[^ac]' shallceshi.sh
ab
Abc
aBcd
hello
hello world

行首字符^与行尾字符$,表示位置而不是字符

$ grep -n '^[a]' shallceshi.sh  #搜索以a开头的字符
1:a
2:ab
4:aBcd
$ grep -n '[o]$' shallceshi.sh #搜索以o结尾的字符
6:hello
$ grep -n '^$' shallceshi.sh #搜索空行
5:

任意一个字符.与重复字符*
字符.表示一个且一定存在,例如'a.c'表示aac、abc、acc、adc…
字符*表示存在0个以上的重复字符,例如'ab*c'表示ac、abc、abbc、abbbc…
'a.*c'表示 a(任意个任意字符,包括空格等)c,如ac、akfsc、adsf c…
如果需要对重复字符的个数进行限制,使用'字符\{下限次数,上限次数\}',如'a\{1,2\}'表示a出现1次或者2次,上下限次数可以不写表示无上下限制次数

$ grep -in 'a.c' shallceshi.sh
3:Abc
4:aBcd
$ grep -in 'el\{1\}o' shallceshi.sh #没有含elo字符串的行
$ grep -in 'el\{2\}o' shallceshi.sh #搜索带有ello的字符串
6:hello
7:hello world

扩展grep -E的用法,也可以写作egrep。举例说明

$ grep -v '^A' shallceshi.sh | grep -v '^$' #去除以A开头的行和空行(未修改原文件)
a
ab
aBcd
hello
hello world
$ grep -vE '^A|^$' shallceshi.sh #两者等同,输出结果一样
a
ab
aBcd
hello
hello world

几个扩展特殊符号(暂未验证):
+,表示一个或多个重复字符
?,表示0个或一个字符
| ,表示或关系,比如'gd|good|dog'表示有gd,good或dog的串
(),将部分内容合成一个单元组。比如要搜索glad或good可以这样'g(la|oo)d',()的好处是可以对小组使用+ ? |等
比如要搜索A和C开头结尾,中间有至少一个(xyz)的串,可以这样:'A(xyz)+C'

十一、拓展符号比较大小

-eq 等于(equal)
-ne 不等于(no equal)
-gt 大于(greater than)
-lt 小于(less than)
-ge 大于等于(greater and equal)
-le 小于等于(less and equal)

echo 比较两个数的大小
echo -n a=
read a
echo -n b=
read b
if [ $a -gt $b ] ; then
   echo a大于b
 elif [ $a -eq $b ] ;then
     echo a等于b
   else
     echo a小于b
fi
十二、sed的用法

这篇写的很详细 https://blog.csdn.net/wdz306ling/article/details/80087889#commentBox
总结一下,格式为 sed -选项 ‘要处理哪些行如何处理处理内容’ 文件名
$ sed -n '1insert' shallceshi.sh表示在shallceshi.sh文件的第一行之前插入nsert
选项:
-i 修改并保存到原文件(默认只预览,不作实质修改)
-n 只显示处理过的行(默认显示全部文件内容)

要处理哪些行:
不写则表示所有行
数字x 处理第x行
数字x,数字y 处理第x到y行
数字x~数字y 处理第(x+ny)行,n=0,1,2,3…
可以匹配得到行,格式为 /匹配内容/ 即处理有匹配内容的行

如何处理:
a… 向某行(可以指定,写在a前面,也可以匹配得到)之后插入一行,内容为…
i… 向某行(可以指定,写在i前面,也可以匹配得到)之前插入一行,内容为…
c… 将某行(可以指定,写在c前面,也可以匹配得到)替换,内容为…
d 删除某行(可以指定,写在d前面,也可以匹配得到)
p 打印某行(可以指定,写在p前面,也可以匹配得到),通常配合-n使用
= 在某行之前插入该行行号,通常配合-n使用
s/字符串1/字符串2/替换第几个 将该行中的字符串1替换成字符串2,默认替换第一个,g表示全部替换(替换的分隔符号/可以替换成#,防止字符串中含有/时造成冲突)
$ sed '/echo/s/asd/zxc/2' shallceshi.sh表示对于shallceshi.sh文件,匹配含有echo的行,将行中的第二个asd替换成zxc
$ sed '/hello/,$d' shallceshi删除匹配到hello及之后的所有行
注:
1、匹配内容:字符串可以用单个任意字符.、\{数字\}表示字符个数或任意个重复字符*、行首符号^、行尾符号$、[0-9]范围(中括号里的^表示取反)、&或\1表示匹配到的内容,在搜索行时在/后加!表示取反,/,+1表示匹配的行和下一行
2、文件名可以使用`命令` 方式得到,例如sed -i '1ihello' `ls`表示在当前所有文件的第一行之前插入一行,内容为hello

$ sed 's/[^0-9]/_/g' shallceshi.sh表示将所有非数字替换成下划线

十三、:的用法

https://www.cnblogs.com/nkwy2012/p/9171408.html

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
回答: 在Linux shell脚本,while循环用于在满足某个条件的情况下重复执行一段代码。while循环的语法格式如下: ``` while \[ condition \] do # 循环执行的代码 done ``` 其,`condition`是一个条件表达式,只有当该条件为真时,循环的代码才会执行。循环执行的过程是,先判断条件是否为真,如果为真,则执行循环的代码,然后再次判断条件是否为真,如果为真,则再次执行循环的代码,以此类推,直到条件为假时,循环结束。 举例来说,如果我们有一个脚本a.sh,其使用while循环输出数字1到5,脚本内容如下: ``` #!/bin/bash i=1 while \[ $i -le 5 \] do echo "$i" let i++ done ``` 执行该脚本,会输出数字1到5,即执行结果为:1 2 3 4 5。\[1\] 另外,我们还可以使用while循环从文件读取内容。例如,我们有一个文件province.txt,其包含一些省份名称,我们可以使用while循环逐行读取该文件的内容并进行处理,脚本内容如下: ``` #!/bin/bash filePath=`pwd` while read line do echo ${line} done < ${filePath}/province.txt ``` 执行该脚本,会逐行输出文件province.txt的内容。\[2\] 总结来说,while循环是一种在满足条件的情况下重复执行代码的结构,可以用于各种不同的场景,根据具体需求来灵活运用。 #### 引用[.reference_title] - *1* *3* [Linux系统Shell脚本第三章:for、while循环及脚本实操](https://blog.csdn.net/weixin_67287151/article/details/128538458)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Shell脚本while循环语句应用](https://blog.csdn.net/zhangbeizhen18/article/details/130913286)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值