首页 > 系统相关 >Linux shell 脚本常用指南

Linux shell 脚本常用指南

时间:2023-08-11 15:56:45浏览次数:41  
标签:指南 shell grep echo sed awk file Linux 匹配

常用语法

变量

#!/bin/bash
# 字符串
USER_NAME="shell"
# 数字
AGE=25
echo ${USER_NAME}
echo ${AGE}

数组

#!/bin/bash
# 普通数组定义
USER_IDS=(1 2 3 4)
echo ${USER_IDS[0]}
echo ${USER_IDS[1]}
echo ${USER_IDS[2]}
echo ${USER_IDS[3]}
USER_IDS[0]=-1
echo ${USER_IDS[0]}
# 关联数组定义
declare -A USER_MAP=(["zhangsan"]="this is zhangsan" ["lisi"]="this is lisi")
echo ${USER_MAP["zhangsan"]}
echo ${USER_MAP["lisi"]}
USER_MAP["zhangsan"]="zhangsan change"
echo ${USER_MAP["zhangsan"]}

流程控制

if else

[]写法(推荐)
if [ "$a" -gt "$b" ]; then
  echo "yes"
fi
#多个条件写法
if [ "$a" -gt "$b" ] && [ "$a" -gt "$b" ] ; then
  echo "yes"
fi
(())写法
if (( a > b )); then
    ...
fi
判断条件表
字符串判断	含义
-n str1	当串的长度大于0时为真(串非空)
-z str1	当串的长度为0时为真(空串)
$a = $b 判断a与b两个字符串是否相等
$a != $b 判断a与b两个字符串不相等
数字的判断	
int1 -eq int2	两数相等为真
int1 -ne int2	两数不等为真
int1 -gt int2	int1大于int2为真
int1 -ge int2	int1大于等于int2为真
int1 -lt int2	int1小于int2为真
int1 -le int2	int1小于等于int2为真
文件的判断	
-r file	用户可读为真(助记:read)
-w file	用户可写为真(助记:write)
-x file	用户可执行为真
-f file	文件为普通文件为真
-c file	文件为字符特殊文件为真
-b file	文件为块特殊文件为真
-d file	文件为目录为真
-s file	文件大小非0时为真
-t file	当文件描述符(默认为1)指定的设备为终端时为真
-a FILE	如果 FILE 存在则为真。
-p FILE	如果 FILE 存在且是一个名字管道(F如果O)则为真
-L FILE	如果 FILE 存在且是一个符号连接则为真
-S FILE	如果 FILE 存在且是一个套接字则为真
复杂逻辑判断	
-a	与
-o	或
!	非

for

user_ids=(1 2 3 4)
for loop in ${user_ids[@]}
do
  echo ${loop}
done
for(( i=0;i<=5;i++ ))
do
  echo $i
done

while

#!/bin/bash
sum=1
while(( ${sum}<=5 ))
do
  echo ${sum}
  sum=`expr ${sum} + 1`
done

函数

一个加法函数

function sum(){
  res=`expr $1 + $2`
  echo ${res}
}
sum 1 3

传递参数

#!/bin/bash  
echo "Shell 传递参数实例!";  
echo "执行的文件名:$0";  
echo "第一个参数为:$1";  
echo "第二个参数为:$2";  
echo "第三个参数为:$3";

输入\输出

命令 说明
command > file 将输出重定向到 file。
command < file 将输入重定向到 file。
command >> file 将输出以追加的方式重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
 

linux三剑客grep、sed、awk

grep查找命令

下面的案例都是用/etc/passwd文件来演示的

常用指令

指令 说明
-A 除了匹配行,额外显示该行之后的N行
-B 除了匹配行,额外显示该行之前的N行
-C 除了匹配行,额外显示该行前后的N行
-c 统计匹配的行数
-e 实现多个选项间的逻辑 or 关系
-E 支持扩展的正则表达式
-F 相当于 fgrep
-i 忽略大小写
-n 显示匹配的行号
-o 仅显示匹配到的字符串
-q 安静模式,不输出任何信息,脚本中常用
-s 不显示错误信息
-v 显示不被匹配到的行
-w 显示整个单词
--color 以颜色突出显示匹配到的字符串

把包含root的行过滤出来

grep "root" /etc/passwd

# 忽略大小写过滤
grep -i "root" /etc/passwd

正则匹配固定开头和结尾的行

# 匹配root开头的行
grep "^root" /etc/passwd

# 匹配/bin/bash结尾的行
grep "/bin/bash$" /etc/passwd

把匹配root的行以及下边两行显示出来

grep -A "root" /etc/passwd

过滤root关键字,并输出行号

grep -n "root" /etc/passwd

删除空行

grep -v "^$" /etc/passwd

过滤包含root或者hzh的行

grep -e "root" -e "hzh" /etc/passwd

其他复杂用法

# 在当前目录递归查询
grep -r "font".

# (显示行号,且以单词严格匹配)
grep -rnw "font" .

# 在递归的过程中排除某些目录
grep -rnw --exclude-dir={.git,svn} "font"

awk命令

awk是一种处理文本文件的语言,是一个强大的文本分析工具,下面使用/etc/passwd文件作案例。

基本命令格式

awk '{pattern + action}' <file>

pattern表示在数据中要查找的内容,action表示要执行的一系列命令

默认空格(一个或多个)分割数据

$1、$2 ... $n 表示第一个字段、第二个字段... 第n个字段

awk '{print $2, $4, $6}' /etc/passwd

指定分隔符

指定:,为分隔符

awk -F ':|,' '{print $2, $4, $6}' /etc/passwd

正则分隔符,指定空格或者,号,一个或多个为分隔符

awk -F'[ |,]+' '{print $1}' awk.txt

内置变量

除了 $1、$2 ... $nawk 还有一些内置变量,常用的如下:

变量 描述
$0 表示当前整行,1表示第一个字段,1表示第一个字段,1表示第一个字段,2表示第二个字段,$n 表示第n个字段;
NR 表示当前已读的行数
NF 表示当前行被分割的列数,NF表示最后一个字段,NF-1 表示倒数第二个字段;
FILENAME 表示当前文件的名称

条件判断

判断第三列大于10的显示整行

awk -F ' |,' '$3 > 10 {print $0}' awk.txt

正则匹配行

匹配包含hzh的行并输出
awk '/hzh/{print $0}' awk.txt
匹配00结尾的并输出
awk '/00$/{print $0}' awk.txt

sed命令

sed 主要是用来将数据进行选取、替换、删除、新増的命令。

语法

sed [选项] '[动作]' 文件名

选项

选项 含义
-e 该选项会将其后跟的脚本命令添加到已有的命令中
-f 该选项会将其后文件中的脚本命令添加到已有的命令中
-n 默认情况下,sed 会在所有的脚本指定执行完毕后,会自动输出处理后的内容,而该选项会屏蔽启动输出,需使用 print 命令来完成输出
-i 此选项会直接修改源文件,要慎用

字符串替换

基本格式
sed 's/pattern/replacement/flags' /etc/passwd
flags取值表
flags标记 功能
n 1~512 之间的数字,表示指定要替换的字符串出现第几次时才进行替换,例如,一行中有 3 个 A,但用户只想替换第二个 A,这是就用到这个标记
g 对数据中所有匹配到的内容进行替换,如果没有 g,则只会在第一次匹配成功时做替换操作。例如,一行数据中有 3 个 A,则只会替换第一个 A;
p 会打印与替换命令中指定的模式匹配的行。此标记通常与 -n 选项一起使用。
w file 将缓冲区中的内容写到指定的 file 文件中;
& 用正则表达式匹配的内容进行替换;
\n 匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。
\ 转义(转义替换部分包含:&、\ 等)。

替换第几次出现的匹配模式

下面的语句替换hello,替换每一行中第二次出现

sed 's/hello/happy/2' sed.txt
替换所有匹配的字符串

如果sed变为sed -i 则表示修改源文件且不输出

sed 's/hello/happy/g' sed.txt
删除指定行
  • 删除第2,3
  • sed '2,3d' sed.txt
  • 删除第1-3
  • sed '/1/,/3/d' sed.txt
  • 删除第2行开始的所有内容
  • sed '2,$d' sed.txt

     

在指定行新增
  • 在第2行后追加
  • sed '2a\append line' sed.txt
  • 在第2行前新增
  • sed '2i\pre line' sed.txt

     

替换指定行
sed '2c\replace line' sed.txt

三剑客取JSON字符串中的指定key

#!/bin/bash
  

result_json='{"code":200,"message":"success","data":null}'

# 取出code
code=`echo ${result_json} | sed 's/\\\"/"/g' | grep -Po '"code":"?\K.*?(?=,|})'`
echo "code=${code}"

message=`echo ${result_json} | sed 's/\\\"/"/g' | grep -Po '"message":"?\K.*?(?=,|}|")'`
echo "message=${message}"

data=`echo ${result_json} | sed 's/\\\"/"/g' | grep -Po '"data":"?\K.*?(?=,|}|")'`
echo "data=${data}"

result_json='{"code":200,"message":"success","data":[{"id":1,"userName":"zhangsan","age":10},{"id":2,"userName":"lisi","age":5}]}'

# 取data中的id、userName、age
id=`echo ${result_json} | sed 's/,/EOF\n/g' | grep -Po '"id":"?\K.*?(?=,|}|EOF)' | sed -n 1p`
echo "id=${id}"

userName=`echo ${result_json} | sed 's/,/EOF\n/g' | grep -Po '"userName":"?\K.*?(?=,|"|}|EOF)' | sed -n 1p`
echo "userName=${userName}"

age=`echo ${result_json} | sed 's/,/EOF\n/g' | grep -Po '"age":"?\K.*?(?=,|}|EOF)' | sed -n 1p`
echo "age=${age}"

id=`echo ${result_json} | sed 's/,/EOF\n/g' | grep -Po '"id":"?\K.*?(?=,|}|EOF)' | sed -n 2p`
echo "id=${id}"

userName=`echo ${result_json} | sed 's/,/EOF\n/g' | grep -Po '"userName":"?\K.*?(?=,|"|}|EOF)' | sed -n 2p`
echo "userName=${userName}"

age=`echo ${result_json} | sed 's/,/EOF\n/g' | grep -Po '"age":"?\K.*?(?=,|}|EOF)' | sed -n 2p`
echo "age=${age}"
  • 运行结果
  • sed 's/\\\"/"/g'
  • 该语句是替换字符串中的\"替换为"
  • grep -Po '"code":"?\K.*?(?=,|})'
  • 该语句是取指定key,后面的值,这里取的是code后面的,:?标识匹配0个或1个,*?(?=,|})表示以什么结尾,最少匹配,匹配到第一个接结束,且字符串不会包含在我们想要的结果中,
  •  
  • sed -n 2p
  • 取第几行的意思
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

    注意点

  •  

     

    单引号'',和双引号""

  •  

    单引号''

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的;
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。
  •  

    双引号""

  • 双引号里可以有变量
  • 双引号里可以出现转义字符
  •  

    shell脚本中获取当前绝对路径

  • fork_sub.sh
  •  
  •  

    #!/bin/bash
    BASE_PATH=$(cd `dirname $0`;pwd)
    echo ${BASE_PATH}
    

    $开头的一些指令含义

      shell 复制代码
    $0:这个程式的执行名字。  
    $n:这个程式的第 n 个参数值,n=1…9。  
    $*:这个程式的所有参数,此选项参数可超过 9 个。  
    $#:这个程式的参数个数。  
    $$:这个程式的 PID(脚本运行的当前进程 ID 号)  
    $!:执行上一个背景指令的 PID (后台运行的最后一个进程的进程 ID 号)  
    $?:执行上一个指令的返回值 (显示最后命令的退出状态。0 表示没有错误,其他任何值表明有错误)  
    $-:显示 shell 使用的当前选项,与 set 命令功能相同。

    shell脚本调用其他shell脚本的三种方式

    fork模式

    fork 是最普通的, 就是直接在脚本里面用 path/to/foo.sh 来调用foo.sh 这个脚本,比如如果是 foo.sh 在当前目录下,就是 ./foo.sh。运行的时候 terminal 会新开一个子 Shell 执行脚本 foo.sh,子 Shell 执行的时候, 父 Shell 还在。子 Shell 执行完毕后返回父 Shell。 子 Shell 从父 Shell 继承环境变量,但是子 Shell 中的环境变量不会带回父 Shell

    • fork.sh

    #!/bin/bash
    echo "fork模式"
    user_name="zhangsan"
    export user_name
    ./fork_sub.sh
    echo ${user_name}
    echo "fork执行完毕"
     
  • fork_sub.sh
  • #!/bin/bash
    echo "输出user_name=${user_name}"
    user_name="张三变了"
    
    • 输出结果
    [root@localhost exec]# bash fork.sh 
    fork模式
    输出user_name=zhangsan
    zhangsan
    fork执行完毕
  • exec模式

    exec 与 fork 不同,不需要新开一个子 Shell 来执行被调用的脚本. 被调用的脚本与父脚本在同一个 Shell 内执行。但是使用 exec 调用一个新脚本以后, 父脚本中 exec 行之后的内容就不会再执行了。这是 exec 和 source 的区别.


    source模式

    与 fork 的区别是不新开一个子 Shell 来执行被调用的脚本,而是在同一个 Shell 中执行. 所以被调用的脚本中声明的变量和环境变量, 都可以在主脚本中进行获取和使用。

标签:指南,shell,grep,echo,sed,awk,file,Linux,匹配
From: https://www.cnblogs.com/liftsail/p/17623162.html

相关文章

  • Linux_CentOS
    windows和macOS是个人桌面操作系统;linux是服务器操作系统一、入门Linux1.1操作系统概述操作系统调度和管理计算机硬件进行工作,调度CPU,内存,硬盘,网卡,音响等发消息-->操作系统-->网卡驱动-->网卡发送数据包-->服务器-->接收计算机由硬件和软件组成,操作系统是软件的一类,主要协助......
  • Linux 系统 基础命令
    目录ls:列出目录下的文件和文件夹名字"mkdir创建新目录(文件夹)//mkdirt01rmdir删除空目录//rmdirt01cd切换目录pwd查看当前所在的工作目录的绝对路径vim文本编辑器touch创建文件cat查看文件全部内容(不用进入内容,只展示内容)(从第一行显示)more命令查看文件内容cp......
  • Shell编程规范与变量二
    目录1.条件测试1.1文件测试1.2数字测试1.3字符串测试1.4逻辑测试1.5双中括号1.6(){}1.7if语句1.7.1单分支1.7.2双分支1.7.3多分支1.8case命令1.9echo命令2.使用shell脚本编译安装nginx1.条件测试条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达......
  • SSH隧道代理实际操作指南
    在如今的互联网时代,许多网站和应用在某些地区受到限制和封锁,导致用户无法自由访问和享受在线资源。为了突破这一限制,SSH隧道代理成为了一种简单有效的工具。本文将详细介绍SSH隧道代理的原理、使用方法以及一些实际操作技巧,让您轻松畅游互联网。在介绍SSH隧道代理之前,我们先了解下S......
  • linux
    目录介绍编号目录含义1/bin存放二进制可执行文件2/boot存放系统引导时使用的各种文件3/dev存放设备文件4/etc存放系统配置文件,比如:安装完毕jdk,安装maven、配置环境变量5/home用户的主目录,存放用户的个人资料的。比如:linux是一个多用户的操作......
  • Linux文件服务器搭建与使用实例
    1.1 NFS是什么?NFS 是网络文件系统 Network FileSystem 的 简称 ,最早是由 Sun 公司 开发 出来 的,目的是想 让 不同的 机器、不同的 操作 系統可以 共享文件。 在 Unix/Linux类的 操作系统 中 可以 用 NFS 来搭建文件服务器。 对于一个真实的运行环境而言......
  • 安装Linux操作系统
    LAMP是一种非常常见的开源软件套件,包括Linux操作系统、ApacheHTTP服务器、MySQL数据库和PHP编程语言。它被广泛应用于构建动态网站和Web应用程序。本文将介绍如何安装和配置LAMP服务器,以实现可靠高性能的网站和应用程序运行环境。一、安装Linux操作系统在安装LAMP之前,首先需要选......
  • JAVA 内存详解 (理解 JVM 如何使用 Windows 和 Linux 上的本机内存)
    级别:中级AndrewHall ,软件工程师,IBM2009年5月11日Java™堆耗尽并不是造成 java.lang.OutOfMemoryError 的惟一原因。如果本机内存 耗尽,则会发生普通调试技巧无法解决的 OutOfMemoryError 。本文将讨论本机内存的概念,Java运行时如何使用它,它被耗......
  • Linux MQTT智能家居项目(智能家居界面布局)
    (文章目录)前言一、创建工程项目1.选择工程名称和项目保存路径2.选择QWidget3.添加保存图片的资源文件:在工程目录下添加Icon文件夹保存图片:将文件放入目录中:将图片添加进入资源文件中:二、界面布局准备工作这里我们一共显示4个界面:LED控制界面,温度湿度显示界面,光......
  • Linux系统修改时区
    本文以修改印度孟买时区为例,请您参考以下步骤进行操作。执行以下命令更新时区。ln-sf/usr/share/zoneinfo/Asia/Colombo/etc/localtime说明:印度有些地区会使用/usr/share/zoneinfo/Asia/Colombo这个GMT+05:30的时间。执行以下命令更新硬件时钟(RTC)。hwclock-w执行以下命令重启......