shell编程总结

一、开始运行

首先在文件开头添加使用#!/bin/bash,意思是使用该shell解释器运行该脚本

echo命令用于输出一句话

#!/bin/bash
echo "Hello world !!!"

然后可以有多种运行shell脚本的方法

1、sh命令运行
root@zxh:~# sh test.sh
2、bash命令运行
root@zxh:~# bash test.sh
3、./方式运行

sh和bash命令都是把当前脚本文件输出给/bin/bash运行,所以只要我们有使用/bin/bash的权限,就能运行。但是使用./的方式运行,就等于直接将本文件输出给系统的解释器运行,此时就需要本文件有执行的权限,所以要先提权,再运行

root@zxh:~# chown 777 test.sh
root@zxh:~# ./test.sh
4、案例一

在当前目录下创建一个叫work.txt的文件,然后写入数据I Yove You。

#!/bin/bash
echo "start touch file!!!"
touch lian.txt
echo "I Love You" >> lian.txt
echo "stop commond!!!"
5、echo

打印字符串。

1、基本用法
  1. 单引号包裹的都转为字符串;

  2. 双引号包裹的可以包含变量,先替换变量,再转为字符串

  3. 连续的字符串可以不使用双引号

  4. 字符串之内有空格,不连续的就要用单引号或双引号包裹起来,否则报错

#!/bin/bash
echo "----------------------------"
a=吃了
echo '吃了吗$a'
echo "吃了吗$a"
echo 吃了吗$a
echo "吃 了吗$a"
echo "----------------------------"
root@zxh:~# ./test.sh 
----------------------------
吃了吗$a
吃了吗吃了
吃了吗吃了
吃 了吗吃了
----------------------------
2、包含转义字符

要使用选项 -e

root@zxh:~# echo "hh\thh"
hh\thh
root@zxh:~# echo -e "hh\thh"
hh      hh
root@zxh:~# echo -e "hh\0112hh"
hhJhh
root@zxh:~# echo -e "hh\0113hh"
hhKhh

常见转义序列

字符含义字符含义
\b后退\f换页
\n换行\r回车
\t水平制表符\v垂直制表符
\\一个反斜杠\0ddd1到3位整数用于表示八进制的字符
root@iZbp18qtvejt7jqx8ghcanZ:~/code/shell_learn# echo -e "hh\0112hh"
hhJhh
root@iZbp18qtvejt7jqx8ghcanZ:~/code/shell_learn# echo -e "hh\0113hh"
hhKhh
3、颜色

文字颜色。使用 \e[1;XXm\e[0m 包裹,中间的文字会变色,XX代表从30-37的数字

#!/bin/bash

echo -e "\e[1;31m你好\e[0m呀"
echo -e "\e[1;36m你好\e[0m呀"
echo -e "\e[1;33m你好\e[0m呀"

在这里插入图片描述

文字颜色码颜色文字颜色码颜色
0重置30黑色
31红色32绿色
33黄色34蓝色
35洋红色36青色
37白色

背景色。使用 \e[1;YYm\e[0m 包裹,中间的部分背景会变色,YY代表从40-47的数字。默认文字为白色

#!/bin/bash

echo -e "\e[1;42m你好\e[0m呀"
echo -e "\e[1;45m你好\e[0m呀"
echo -e "\e[1;46m你好\e[0m呀"

在这里插入图片描述

文字颜色和背景色支持嵌套,只需要一个 \e[0m 结尾即可

#!/bin/bash

echo -e "\e[1;41m   \e[1;34m你好\e[0m  \e[0m呀"
echo -e "\e[1;41m   \e[1;34m你好  \e[0m呀"

在这里插入图片描述

二、变量

1、普通变量的赋值、使用和取消

变量赋值变量名=值,如a=2,等号两边不能有空格

使用变量。** 变 量 名 ∗ ∗ , 如 ‘ 变量名**,如 ` a`

#!/bin/bash
echo "----------------------------"
p=$USER
echo $p
echo "----------------------------"
#结果
#----------------------------
#root
#----------------------------

取消变量的使用。unset命令

#!/bin/bash
echo "----------------------------"
p=$USER
unset p
echo $p
echo "----------------------------"
#结果
#----------------------------
#
#----------------------------

只读变量。普通变量可以被取消,但是可以定义一个只读变量,除非系统重启,否则不可被取消

#!/bin/bash
echo "----------------------------"
readonly p=$USER
unset p
echo $p
echo "----------------------------"
#结果
#----------------------------
#./one.sh: line 4: unset: p: cannot unset: readonly variable
#root
#----------------------------

变量默认为字符串类型,不能进行数值运算

#!/bin/bash
echo "----------------------------"
p=1+5
echo $p
echo "----------------------------"
#结果
#----------------------------
#1+5
#----------------------------

定义的字符串中间有空格就要使用单引号或双引号括起来

#!/bin/bash
echo "----------------------------"
n=hello world
echo $n
y="hello world"
echo $y
echo "----------------------------"
#结果
#----------------------------
#./one.sh: line 3: world: command not found
#
#hello world
#----------------------------
2、全局变量

a=2这种方式定义的变量只是普通的局部变量,该变量只能在该脚本运行时,且只能在该脚本内使用,其他脚本不能使用,因此可以直接定义全局变量(export n=1)或者提升普通变量为全局变量(n=1后export n)

#!/bin/bash
echo "----------------------------"
echo $n
echo "----------------------------"
root@zxh:~# ./one.sh 
----------------------------

----------------------------
root@zxh:~# export n=1000000
root@zxh:~# ./one.sh 
----------------------------
1000000
----------------------------

上面在脚本文件中输出变量n,但是没有定义这个n,运行时输出为空,在bash控制台设置全局变量,之后再次运行脚本,脚本就可以找到全局变量n了。

注意:

  • 如果有同名的局部变量,优先使用局部变量
  • 该全局变量的生命周期为脚本运行时,脚本关闭,该全局变量也就失效了
  • bash控制台和自己写的脚本本质是一样的,也就是说,正在运行的控制台也是一个脚本
3、系统变量

常用的系统变量 H O M E 、 HOME、 HOMEPWD、 S H E L L 、 SHELL、 SHELLUSER、$PATH……。

  • $HOME代表当前用户的家目录
  • $PWD代表当前所在目录
  • $SHELL代表使用的是哪个shell解释器
  • $USER代表当前用户名
  • $PATH代表系统变量
#!/bin/bash
echo "----------------------------"
echo $HOME
echo "----------------------------"
root@zxh:~# ./test.sh
----------------------------
/root
----------------------------
4、特殊变量(重点)
1)$number
参数含义
$0脚本文件名字
$1启动脚本时传的第一个参数
$2启动脚本时传的第二个参数
$3启动脚本时传的第三个参数
…………
$(10)启动脚本时传的第十个参数,十个或以上要用括号
$(11)启动脚本时传的第十一个参数
…………
#!/bin/bash
echo "----------------------------"
echo $0
echo $1
echo $2
echo "----------------------------"
root@zxh:~# ./test.sh 666 888
----------------------------
./test.sh
666
888
----------------------------
root@zxh:~# sh test.sh 666 888
----------------------------
test.sh
666
888
----------------------------
2)$#

获取所有输入参数个数(该参数常用于循环中)

#!/bin/bash
echo "----------------------------"
echo $#
echo "----------------------------"
root@zxh:~# ./test.sh 666 888
----------------------------
2
----------------------------
root@zxh:~# sh test.sh 666 888
----------------------------
2
----------------------------
3)$* 和 $@

$*代表命令行中所有的参数,把所有的参数看成一个不可区分的整体

$@代表命令行中所有的参数,把所有的参数看成一个可区分的整体(可用循环迭代)

具体区别,查看for循环的应用

4)$?

代表前面最后一次的命令的执行状态。

  • 如果执行正常,结果为0
  • 如果执行失败,结果不固定,由命令本身决定
#!/bin/bash
echo "----------------------------"
cat "hhhh"
echo "Error code: "$?
$?
echo "Error code: "$?
echo "yeye"
echo "Error code: "$?
echo "----------------------------"
#结果
#----------------------------
#cat: hhhh: No such file or directory
#Error code: 1
#test.sh: 5: test.sh: 0: not found
#Error code: 127
#yeye
#Error code: 0
#----------------------------

三、字符串操作

1、获取字符串长度
#!/bin/bash
data="myname"
echo ${#data}
#结果
#6
2、截取字符串

${变量名:位置起点} 。从起点到结束,起点从0开始

#!/bin/bash
data="myname"
echo ${data:2}
#结果
#name

${变量名:位置起点:长度} 。从起点到指定长度

#!/bin/bash
data="myname"
echo ${data:2:3}
#结果
#nam
3、替换字符串

${变量/样式/替换字符串} 。如果变量中有符合样式的字符串,则使用替换字符串替代该样式,只替换第一个符合的样式

#!/bin/bash
data="hello lili hello niuniu"
echo ${data/hello/good}
# 结果
#good lili hello niuniu

${变量//样式/替换字符串} 。如果变量中有符合样式的字符串,则使用替换字符串替代该样式,替换全部符合的样式

#!/bin/bash
data="hello lili hello niuniu"
echo ${data//hello/good}
# 结果
#good lili good niuniu
4、提取字符串

${变量#*样式} 。从最左边开始与样式比对 ,将寻找到的第一个作为分隔符,删除左边,只剩下右边字符串

#!/bin/bash
str="say hello python hello golang hello c"
echo ${str#*he}
#结果
#llo python hello golang hello c

${变量%样式*} 。从最右边开始与样式比对 ,将寻找到的第一个作为分隔符,删除右边,只剩下左边字符串

#!/bin/bash
str="say hello python hello golang hello c"
echo ${str%he*}
#结果
#say hello python hello golang

${变量##*样式} 。从最左边开始与样式比对 ,将寻找到的最后一个作为分隔符,删除左边,只剩下右边字符串

#!/bin/bash
str="say hello python hello golang hello c"
echo ${str##he*}
#结果
#llo c

${变量%%样式*} 。从最右边开始与样式比对 ,将寻找到的最后一个作为分隔符,删除右边,只剩下左边字符串

#!/bin/bash
str="say hello python hello golang hello c"
echo ${str%%he*}
#结果
#say
5、字符串拼接
#!/bin/bash
str1="hello"
str2="$str1 world"
str3=$str1$str2
echo $str2
echo $str3
#结果
#hello world
#hellohello world

四、运算符

1、expr

运算符可以使用 加(+)、减(-)、乘(\*)、除(/)、余(%)。运算符间要有空格。可以嵌套,使用反引号括起来表示先运行

#!/bin/bash
echo "----------------------------"
expr `expr 2 + 4` \* 5
echo "----------------------------"
#结果
#----------------------------
#30
#----------------------------
2、let
#!/bin/bash
num1=11
num2=22
let num3=num1+num2
echo $num3
let sum=11+22
echo $sum
#结果
#33
#33
3、bc计算器

bc计算器是系统内部的计算器,我们只要传计算式子给bc计算器即可,传递过程使用到管道符

#!/bin/bash
num1=7
num="(1+3)*4/2%$num1"
echo $num | bc
#结果
#1
2、$[表达式子]

运算符可以使用 **加(+)、减(-)、乘(*)、除(/)、余(%)**表达式内部没有空格。不能使用sh命令启动脚本

#!/bin/bash
echo "----------------------------"
s=$[(5+8)*2]
echo $s
echo "----------------------------"
root@zxh:~# ./test.sh 
----------------------------
26
----------------------------
root@zxh:~# bash test.sh 
----------------------------
26
----------------------------
root@zxh:~# sh test.sh 
----------------------------
test.sh: 3: test.sh: Syntax error: "(" unexpected
3、$((表达式子))(常用)

表达式内对空格没有要求,使用小括号作为运算优先符号,常用这个方式作为运算式子

#!/bin/bash
echo "----------------------------"
s=$((((5 + 8) % 2) + 1))
echo $s
echo "----------------------------"
#结果
#----------------------------
#2
#----------------------------

五、条件判断

[ condition ],condition前后要有空格,condition为true或者false

1、两个整数之间的比较
符号含义
=字符串比较是否相同
-eq等于(equal)
-lt小于(less than)
-le小于等于(less equal)
-gt大于(greater than)
-ge大于等于(greater equal)
-ne不等于(not equal)
#!/bin/bash
echo "----------------------------"
echo '$?正确则为0,错误则为其他'
[ 33 -ge 11 ]
echo $?
[ 33 -le 11 ]
echo $?
echo "----------------------------"

#结果
#----------------------------
#$?正确则为0,错误则为其他
#0
#1
#----------------------------
root@zxh:~# [ "hhh" = "hh" ]
root@zxh:~# echo $?
1
root@zxh:~# [ "hhh" = "hhh" ]
root@zxh:~# echo $?
0
2、按照文件权限进行判断
符号含义
-r有读的权限(read)
-w有写的权限(write)
-x有执行的权限(execute)
root@zxh:~# touch hhh.txt
root@zxh:~# [ -r hhh.txt ]
root@zxh:~# echo $?
0
root@zxh:~# [ -w hhh.txt ]
root@zxh:~# echo $?
0
root@zxh:~# [ -x hhh.txt ]
root@zxh:~# echo $?
1
3、按照文件类型进行判断
符号含义
-f文件存在并且是一个常规的文件(file)
-e文件存在(existence)
-d文件存在并且是一个目录(directory)
-s文件大小是否大于0
root@zxh:~# touch hhh.txt
root@zxh:~# ls
hhh.txt  test.sh
root@zxh:~# [ -f hhh.txt ]
root@zxh:~# echo $?
0
root@zxh:~# [ -e hhh.txt ]
root@zxh:~# echo $?
0
root@zxh:~# [ -e test.txt ]
root@zxh:~# echo $?
1
root@zxh:~# [ -d hhh.txt ]
root@zxh:~# echo $?
1
root@zxh:~# touch hhh.txt
root@zxh:~# [ -s hhh.txt ]
root@zxh:~# echo $?
1
root@zxh:~# echo "ni niu bi a" >> hhh.txt 
root@zxh:~# [ -s hhh.txt ]
root@zxh:~# echo $?
0
4、复杂逻辑判断
符号含义
-a
-o
!
root@zxh:~# [ 11 -lt 12 -a  12 -lt 13 ]
root@zxh:~# echo $?
0
root@zxh:~# [ 11 -lt 12 -a  12 -eq 13 ]
root@zxh:~# echo $?
1

六、流程控制(重点)

1、if判断

if 关键字后要跟一个空格,然后加条件判断,then 关键字可以写在下一行,也可以写在当前行,写在当前行前面要有分号。然后写程序。最后使用 fi 关键字结尾

if [ 表达式子 ];then
	程序
elif [ 表达式子 ];then
	程序
else
	程序
fi

#-------或者--------

if [ 表达式子 ]
	then
		程序
elif [ 表达式子 ]
	then
		程序
else
	程序
fi
#!/bin/bash
if [ $1 -gt 11 ]
then
    echo "你输入的数字大于11"
elif [ $1 -eq 11 ]
then
    echo "你输入的数字等于11"
else
    echo "你输入的数字小于11"
fi
root@zxh:~# bash test.sh 10
你输入的数字小于11
root@zxh:~# bash test.sh 11
你输入的数字等于11
root@zxh:~# bash test.sh 12
你输入的数字大于11
2、case语句
case $变量名 in
    "值1")
        程序
        ;;
    "值2")
        程序
        ;;
    "值3")
        程序
        ;;
esac
#!/bin/bash
case $1 in
    "11")
        echo "你输入11"
        ;;
    12)
        echo "你输入12"
        ;;
    "13")
        echo "你输入13"
        ;;
esac
root@zxh:~# bash test.sh 11
你输入11
root@zxh:~# bash test.sh 12
你输入12
root@zxh:~# bash test.sh 13
你输入13
root@zxh:~# bash test.sh 14

3、for循环

第一种写法

for ((初始值;循环控制条件;变量变化))
do
    程序
done
#!/bin/bash
sum=0
for ((i=1; i<=5; i++))
do
    sum=$(($i+$sum))
done
echo $sum

#结果
#15

第二种写法

for 变量 in 值1 值2 值3……
do
	程序
done
#!/bin/bash
for num1 in $*
do
    echo $num1
done
for num2 in $@
do
    echo $num2
done
root@zxh:~# ./test.sh 11 22 33
11
22
33
11
22
33
#!/bin/bash
for num1 in "$*"
do
    echo $num1
done
for num2 in "$@"
do
    echo $num2
done
root@zxh:~# ./test.sh 11 22 33
11 22 33
11
22
33
4、while循环
while [ 条件判断式 ]
do
	程序
done
#!/bin/bash
i=1
while [ $i -le 4 ]
do
    echo $i
    i=$(($i + 1))
done
#结果
#1
#2
#3
#4

七、数组

1、数组的定义

变量名[下标]=值 或者 变量名=(值1 值2 值3……)

#!/bin/bash
arr=(666 777 888)
arr[3]=999
echo ${arr[*]}
#结果
#666 777 888 999
2、数组的访问
#!/bin/bash
arr=(666 777 888 999)
echo "数组的长度:"${#arr[*]}
echo "数组的第二个元素:"${arr[1]}
echo "数组的所有元素:"${arr[*]}
echo "数组的所有元素:"${arr[@]}
echo "数组的所有下标:"${!arr[*]}
echo "从第2个元素开始到结束:"${arr[*]:1}
echo "从第2个元素开始到后面1个:"${arr[*]:1:1}

#结果
#数组的长度:4
#数组的第二个元素:777
#数组的所有元素:666 777 888 999
#数组的所有元素:666 777 888 999
#数组的所有下标:0 1 2 3
#从第2个元素开始到结束:777 888 999
#从第2个元素开始到后面1个:777
3、删除数组元素

unset 数组名[下标] 。使用关键字unset删除数组元素,如果直接加数组名就是删除数组

#!/bin/bash
arr=(666 777 888 999)
unset arr[1]
echo "数组的长度:"${#arr[*]}
echo "数组的第二个元素:"${arr[1]}
echo "数组的所有元素:"${arr[*]}
echo "数组的所有下标:"${!arr[*]}

#结果
#数组的长度:3
#数组的第二个元素:
#数组的所有元素:666 888 999
#数组的所有下标:0 2 3
4、数组的修改

给定位置修改

#!/bin/bash
arr=(666 777 888 999)
arr[1]=555
echo ${arr[*]}
#结果
#666 555 888 999

查找替换修改

#!/bin/bash
arr=(666 777 888 999)
echo ${arr[*]/777/555}
#结果
#666 555 888 999
5、数组的遍历
#!/bin/bash
arr=(666 777 888 999)
unset arr[1]

for ((i = 0; i < ${#arr[@]}; i++)); do
    echo ${arr[$i]}
done
echo "使用for(())的方式遍历时,若有元素被删除就遍历异常"
for j in ${arr[@]}; do
    echo $j
done
echo "使用for in的方式遍历时,正常"

#结果
#666
#
#888
#使用for(())的方式遍历时,若有元素被删除就遍历异常
#666
#888
#999
#使用for in的方式遍历时,正常

七、read读取控制台输入

read (选项)(选项值) 变量名

选项:

  • -p:指定读取值时,控制台的提示符
  • -t:指定读取值时,等待的时间(秒)

变量名:用于接收控制台传来的值

#!/bin/bash
read -p "5秒内输入你所想:" -t 5 deam
echo $deam
root@zxh:~# ./test.sh
5秒内输入你所想:3456
3456
root@zxh:~# ./test.sh
5秒内输入你所想:
#不输入内容,5秒后自动关闭

八、printf输出

和C语言的printf函数类似

#!/bin/bash
a=100
printf "math:%-10d分\n" $a
printf "math:%10d分\n" $a
#结果
#math:100       分
#math:       100分

格式替代符如下表

符号含义
%b相对应的参数被视为含有要被处理的转义序列之字符串
%cASCII字符。显示相对应参数的第一个字符
%d或%i对应十进制数字格式
%e或%E或%f对应浮点格式
%o不带正负号的八进制值(字母O)
%s字符串
%u不带正负号的十进制数
%%字面意义的%
%x或(%X)不带正负号的十六进制数,a-f表示10-15(A-F表示10-15)

同时也支持转义序列

九、函数

1、系统函数

类似php那样有很多系统函数,在shell解释器中就已有了,我们只要调用就行了

1)basename

basename [pathname] [suffix] 。给定一个路径字符串,然后取出文件名全称,suffix为后缀名,如果指定后缀名,则取出文件名后再去掉后缀名

root@zxh:~# basename ~/code/shell_learn/hhh.txt
hhh.txt
root@zxh:~# basename ~/code/shell_learn/hhh.txt .txt
hhh
root@zxh:~# basename ~/code/shell_learn/hhh.txt xt
hhh.t
2)dirname

dirname 文件绝对路径 。从给定的绝对路径中,去掉文件名,只留下目录部分

不能是相对路径,如 ./ 或 …/

root@zxh:~# dirname ~/code/shell_learn/hhh.txt 
/root/code/shell_learn
root@zxh:~# dirname ./hhh.txt 
.
root@zxh:~# dirname /root/code/shell_learn/hhh.txt 
/root/code/shell_learn
3)sleep

自定义暂停时间

#!/bin/bash
echo "hello"
sleep 3.5
echo "hi"
#结果
#hello
# 这里等待3.5秒
#hi
2、自定义函数
基本格式:
[function] funname [( )]{
	程序;
	[return int;]
}
调用:
funname
  • 先申明再调用
  • 函数的返回值只能通过$?系统变量获得
  • 如果不使用return语句返回数值,默认使用函数最后一条命令运行结果作为返回值
  • return后面跟数值。(0 - 255)
#!/bin/bash
function sum(){
    s=0
    for i in $@
    do
        s=$(($s+$i))
    done
    return $s
}
sum $@
echo $?
root@zxh:~# ./test.sh 1 2 3 4
10

程序从上往下逐行运行,遇到函数的申明时并不会调用。函数使用的系统变量不能直接调用脚本的系统变量,必须只能在调用函数时给函数传递。如果不传递参数,函数内部只能使用普通的自定义变量

十、工具

1、cut

从文件的每一行剪切字节、字符和字段,并将这些输出。cut [选项参数] filename

选项参数功能
-f指定提取第几列
-d指定按照某分隔符分隔列,如果不指定默认是制表符
#!/bin/bash

cut -d "," -f 1,3 hhh.csv
# 指定切割符为一个空格,就可以将数据切割成3列了,取出第1和第3列
root@zxh:~# cat hhh.csv
id,name,age
1,zhong,18
2,zhang,19
3,xiao,20
4,yang,21
root@zxh:~# ./test.sh 
id,age
1,18
2,19
3,20
4,21

还可以结合其他命令和管道符进行多次的过滤操作。-f参数的数字后面添加 - 符号代表到结束

#!/bin/bash

cat hhh.csv | grep an|  cut -d "," -f 2-
# 查看文件,并寻找出包含“an”字符的行,然后将找出的行的数据传给cut进行操作
#结果
#zhang,19
#yang,21

实例:查看eth0网卡的IP

root@zxh:~# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:16:3e:14:ef:bc brd ff:ff:ff:ff:ff:ff
    inet 172.17.42.167/18 brd 172.17.63.255 scope global dynamic eth0
       valid_lft 307325133sec preferred_lft 307325133sec
root@zxh:~# ip addr show eth0 |grep "inet"
    inet 172.17.42.167/18 brd 172.17.63.255 scope global dynamic eth0
root@zxh:~# ip addr show eth0 |grep "inet" | cut -d " " -f 6
172.17.42.167/18
root@zxh:~# ip addr show eth0 |grep "inet" | cut -d " " -f 6 | cut -d "/" -f 1
172.17.42.167
2、sed

一次处理一行内容,然后输出到控制台,该操作的所有数据都是在缓冲区中进行修改,并不会修改原文件

sed [选项参数] ‘command’ filename

选项参数功能
-e直接在指令模式上进行sed的动作编辑,即可以保证使用多个命令
命令功能
a新增,a的后面可以接字符串,然后再下一行出现
d查找删除
s查找并替换
#!/bin/bash

sed "2a 3 niubi 28" hhh.csv
# 第2(2)行的后面添加(a)字符串(3 niubi 28),对hhh.csv文件进行操作
root@zxh:~# ./test.sh 
id,name,age
1,zhong,18
3 niubi 28
2,zhang,19
3,xiao,20
4,yang,21
root@zxh:~# cat hhh.csv   # 文件没有被修改
id,name,age
1,zhong,18
2,zhang,19
3,xiao,20
4,yang,21
#!/bin/bash

sed "1d" hhh.csv
# 删除第1行
sed "/an/d" hhh.csv
# 查找所有包含“an”的行,然后删除(d),对hhh.csv文件进行操作
root@zxh:~# ./test.sh 
1,zhong,18
2,zhang,19
3,xiao,20
4,yang,21
id,name,age
1,zhong,18
3,xiao,20
#!/bin/bash

sed "s/zh/giao/g" hhh.csv
# 查找“zh”字符,替换成“giao”字符,查找区间为全局(g全称global)
root@zxh:~# ./test.sh 
id,name,age
1,giaoong,18
2,giaoang,19
3,xiao,20
4,yang,21

案例:删除文件中的第4和第5行,然后替换“ng”字符为“giao”字符

#!/bin/bash

sed -e "4,5d" -e "s/ng/giao/g" hhh.csv

#结果
#id,name,age
#1,zhogiao,18
#2,zhagiao,19
3、awk

把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行分析处理

awk [选项参数] ‘pattern1{action1} pattern2{action2}……’ filename

  • pattern:表示awk在数据中查找的匹配模式

  • action:表示在找到匹配内容时所执行的一系列命令

选项参数功能
-F指定分隔符
-v自定义一个变量
#!/bin/bash

awk -F "," '/^[0-9]/ {print $1$2}' hhh.csv
# awk取出一行,然后根据正则表达式(/^[0-9]/)以数字0到9开头,匹配符合要求的行,然后按照分隔符(",")切割,然后运行指定命令(print $1$2)输出第1和第2列
#结果
#1zhong
#2zhang
#3xiao
#4yang
#!/bin/bash

cat hhh.csv
awk -F "," -v i=1 '/^[0-9]/{print $1,$2,$3+i}' hhh.csv
# 取出以数字开头的行,并将第3列的数字加1
#结果
#id,name,age
#1,zhong,18
#2,zhang,19
#3,xiao,20
#4,yang,21
#-------------
#1 zhong 19
#2 zhang 20
#3 xiao 21
#4 yang 22

案例一:使用awk在控制台第一行输出字符“ID NAME”,找到以数字开头的行,然后输出第1和第2列,在控制台最后一行输出字符”number giao“。(关键字BEGIN表示开始匹配之前,END表示匹配之后

#!/bin/bash

awk -F "," 'BEGIN{printf "ID NAME\n"} /^[0-9]/{print $1,$2} END{printf "number giao\n"}' hhh.csv

#结果
#ID NAME
#1 zhong
#2 zhang
#3 xiao
#4 yang
#number giao
4、sort

将文件排序,并将结果标准输出

sort (选项) (参数)

选项功能
-n按照数值的大小排序
-r以相反的顺序排序
-t设置排序时所用到的分隔字符
-K指定需要排序的列

参数:指定待排序的文件列表

#!/bin/bash
cat hhh.csv
echo "------以逗号分割按照第三列顺序排序-------"
sort -t "," -n -k 3 hhh.csv
echo "------以逗号分割按照第三列倒序排序-------"
sort -t "," -r -k 3 hhh.csv
root@zxh:~#./test.sh 
id,name,age
3,xiao,20
1,zhong,18
4,yang,21
2,zhang,19
------以逗号分割按照第三列顺序排序-------
id,name,age
1,zhong,18
2,zhang,19
3,xiao,20
4,yang,21
------以逗号分割按照第三列倒序排序-------
id,name,age
4,yang,21
3,xiao,20
2,zhang,19
1,zhong,18
  • 2
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值