加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
shell.org 18.77 KB
一键复制 编辑 原始数据 按行查看 历史
Sniper 提交于 2023-02-22 10:35 . update sed.

linux shell

比较

文件比较运算符 -e filename 如果 filename存在,则为真 [ -e /var/log/syslog ] -d filename 如果 filename为目录,则为真 [ -d /tmp/mydir ] -f filename 如果 filename为常规文件,则为真 [ -f /usr/bin/grep ] -L filename 如果 filename为符号链接,则为真 [ -L /usr/bin/grep ] -r filename 如果 filename可读,则为真 [ -r /var/log/syslog ] -w filename 如果 filename可写,则为真 [ -w /var/mytmp.txt ] -x filename 如果 filename可执行,则为真 [ -L /usr/bin/grep ] filename1-nt filename2 如果 filename1比 filename2新,则为真 [ /tmp/install/etc/services -nt /etc/services ] filename1-ot filename2 如果 filename1比 filename2旧,则为真 [ /boot/bzImage -ot arch/i386/boot/bzImage ]

如果存在某文件,则删除

if [ -f trials ]; then rm ${result_path}trials; fi

如果没有文件夹,则创建

if [ ! -d $result_name ];then
   mkdir -p $result_name
fi

字符串比较运算符 (请注意引号的使用,这是防止空格扰乱代码的好方法) -z string 如果 string长度为零,则为真 [ -z “$myvar” ] -n string 如果 string长度非零,则为真 [ -n “$myvar” ] string1= string2 如果 string1与 string2相同,则为真 [ “$myvar” = “one two three” ] string1!= string2 如果 string1与 string2不同,则为真 [ “$myvar” != “one two three” ]

算术比较运算符 num1-eq num2 等于 [ 3 -eq $mynum ] num1-ne num2 不等于 [ 3 -ne $mynum ] num1-lt num2 小于 [ 3 -lt $mynum ] num1-le num2 小于或等于 [ 3 -le $mynum ] num1-gt num2 大于 [ 3 -gt $mynum ] num1-ge num2 大于或等于 [ 3 -ge $mynum ]

另外:-a表示and ,-o表示or

if [ $# -eq 2 ] -a [ $2 -eq 1 ]

或的表达方式

if [ "$a" = 1 ] || [ "$a" = "2" ];then
    echo $a
fi

且的表达方式

if [ "$a" = 1 ] && [ "$a" = "2" ];then
  echo $a
fi

变量

##Shell 变量分为 3 种:

用户自定义变量 预定义变量 环境变量 ###1.用户自定义变量

用户自定义变量只支持字符串类型,不支持其他字符,浮点等类型,常见有这 3 个前缀:

1.unset:删除变量

  1. readonly:标记只读变量
  2. export:指定全局变量

4.env 或者printenv:查看所有的环境变量

自己定义变量需要注意下面 2 点:

等号前后不要有空格:NUM=10 一般变量名用大写:VAR=1

调用变量的方法:使用$符号加上变量,可以调用该变量,比如 $VAR

###2.预定义变量 预定义变量常用来获取命令行的输入,有下面这些:

$0 :脚本文件名 $1-9 :第 1-9 个命令行参数名 $# :命令行参数个数 $@ :所有命令行参数 $* :所有命令行参数 $? :前一个命令的退出状态,可用于获取函数返回值 $$ :执行的进程 ID

###3.环境变量

环境变量默认就存在,常用的有下面这几个:

HOME:用户主目录 PATH:系统环境变量 PATH TERM:当前终端 UID:当前用户 ID PWD:当前工作目录,绝对路径

命令

##shell常用关键字

shell常用的关键字如下:

echo:打印文字到屏幕 exec:执行另一个 Shell 脚本 read:读标准输入 expr:对整数型变量进行算术运算 test:用于测试变量是否相等、 是否为空、文件类型等 exit:退出 who: 显示当前登陆系统的用户。包括使用者ID,终端机等 tee:读取标准输入文件,并将其内容输出为文件

例如: who | tee output 表示将who命令的标准输出复制到output文件

tput

https://man.linuxde.net/tput

eval

mktemp

mktemp命令被用来创建临时文件供shell脚本使用。

wait

wait命令用来等待指令的指令,直到其执行完毕后返回终端。 该指令常用于shell脚本编程中,待指定的指令执行完成后,才会继续执行后面的任务。 该指令等待作业时,在作业标识号前必须添加备份号”%”。

read

read命令从键盘读取变量的值,通常用在shell脚本中与用户进行交互的场合。 该命令可以一次读取多个变量的值,变量和输入的值都需要使用空格隔开。 在read命令后面,如果没有指定变量名,读取的数据将被自动赋值给特定的变量REPLY

readlink

readlink是Linux系统中一个常用工具,主要用来找出符号链接所指向的位置

sed

sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用

sed [options] 'command' file(s)
sed [options] -f scriptfile file(s)

[options]:
-e<script>或--expression=<script>: 以选项中的指定的script来处理输入的文本文件
-f<script文件>或--file=<script文件>:以选项中指定的script文件来处理输入的文本文件
-i :直接编辑文件
-h或--help:显示帮助
-n或--quiet或--silent:仅显示script处理后的结果,常与-p命令一起使用表示仅打印输出那些进行命令操作的行
-v或--version:显示版本信息

sed命令

a\ 在当前行下面插入文本。
i\ 在当前行上面插入文本。
c\ 把选定的行改为新的文本。
d 删除,删除选择的行。
D 删除模板块的第一行。
s 替换指定字符
h 拷贝模板块的内容到内存中的缓冲区。
H 追加模板块的内容到内存中的缓冲区。
g 获得内存缓冲区的内容,并替代当前模板块中的文本。
G 获得内存缓冲区的内容,并追加到当前模板块文本的后面。
l 列表不能打印字符的清单。
n 读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。
N 追加下一个输入行到模板块后面并在二者间嵌入一个新行,改变当前行号码。
p 打印模板块的行。
P(大写) 打印模板块的第一行。
q 退出Sed。
b lable 分支到脚本中带有标记的地方,如果分支不存在则分支到脚本的末尾。
r file 从file中读行。
t label if分支,从最后一行开始,条件一旦满足或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
T label 错误分支,从最后一行开始,一旦发生错误或者T,t命令,将导致分支到带有标号的命令处,或者到脚本的末尾。
w file 写并追加模板块到file末尾。
W file 写并追加模板块的第一行到file末尾。
! 表示后面的命令对所有没有被选定的行发生作用。
= 打印当前行号码。
# 把注释扩展到下一个换行符以前

sed替换标记

g 表示行内全面替换。
p 表示打印行。
w 表示把行写入一个文件。
x 表示互换模板块中的文本和缓冲区中的文本。
y 表示把一个字符翻译为另外的字符(但是不用于正则表达式)。
\1 子串匹配标记 。
& 已匹配字符串标记。

sed元字符集

^ 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
/*/  匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] 匹配一个指定范围内的字符,如/[Ss]ed/匹配sed和Sed。
[^] 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& 保存搜索字符用来替换其他字符,如s/love/**&**/,love这成**love**。
\< 匹配单词的开始,如:/\ 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。

sed用法实例

  1. 替换操作:s命令
sed 's/book/books/' file         # 将file文件中每一行的第一个book替换为books
  1. 全面替换标记g
sed 's/book/books/g' file      # 替换file文件每一行中的所有匹配
# 当需要从第N处匹配开始替换时,可以使用/Ng
sed 's/book/books/2g' file    # 从file每一行第二个匹配的开始替换

3. 定界符

以上命令中字符 / 在sed中作为定界符使用,也可以使用其他的任意定界符:

sed 's:test:TEXT:g' file             # 以:作为定界符
sed 's|test|TEXT|g' file             # 以|作为定界符
# 定界符出现在式样内部时,需要进行转义
sed 's/\/bin\/bash/bin/g' file          # 将/bin/bash替换为bin

sed命令查找两个或者两个以上字符串(|是或者的意思) sed -n ‘/字符串1\|字符串2/p’ 文件名 sed -n ‘/aaa\|bbb/p’ 文件名

sed命令查找某个字符串对应的行号 sed -n ‘/字符串1\|字符串2/=’ 文件名

  1. 删除操作:d命令
sed '/^$/d' file          # 删除空白行
sed '2d' file             # 删除第二行
sed '$d' file             # 删除最后一行
sed '2,$d' file           # 删除第二行到最后一行
sed '/^test/d'            # 删除所有以test开头的行
  1. 已匹配字符串标记&

正则表达式\w\+匹配到的每一个单词,使用[&]替换他,&对应于之前匹配到的单词

echo this is a test line | sed 's/\w\+/[&]/g'
[this] [is] [a] [test] [line]

# 所有以192.168.01开头的行都会被替换成自己加上localhost:
sed 's/^192.168.01/&localhost/' file
192.168.01localhost
  1. 子串匹配标记\1

匹配给定样式其中的一部分

echo this is digit 7 number | sed 's/digit \([0-9]\)/\1/'
this  is 7 number
# 命令中digit 7 被替换成了7。样式匹配到的子串是7,\(\)用于匹配子串,
# 对于匹配到的子串第一个就标记为\1,以此类推,匹配到的第二个子串是\2
echo aaa bbb | sed 's/\([a-z]\+\) \([a-z]\+\)/\2 \1/'
bbb aaa

sed -n 's/\(love\)able/\1rs/p' file    # 将file中的loveable替换为lovers,并打印出来
lovers
  1. 组合多个表达式

sed ‘表达式’ | sed ‘表达式’ <==> sed ‘表达式;表达式’

  1. 引用

sed 表达式可以使用单引号来引用,但是如果表达式内部包含变量字符串,就需要使用双引号

test=hello echo hello WORLD | sed “s/$test/HELLO/” HELLO WORLD

  1. 选定行的范围:,(逗号)
# 所有在模板test和check所确定的范围内的行都被打印
sed -n '/test/,/check/p' file

# 打印第五行开始到第一个包含以test开头的行之间的所有行
sed -n '5,/^test/p' file

# 对于模板test和west之间的行,每行的末尾用字符aaa bbb替换
sed '/test/,/west/s/$/aaa bbb/' file
  1. 多点编辑:e命令

-e选项允许在同一行里执行多条命令

sed -e '1,5d' -e 's/test/check/' file
# 第一条命令删除1至5行,第二条命令用check替换test。
# 命令执行顺序对结果有影响,如果两个都是替换命令那么第一个替换命令将影响第二个替换命令的结果
  1. 从文件读入:r命令
# file里的内容被读进来,显示在与test匹配的行后面,如果匹配多行,则file的内容将显示在所有匹配行的下面
sed '/test/r file' filename

写入文件:w命令

# 在example中所有包含test的行都被写入file里
sed -n '/test/w file' example
  1. 追加(行下):a\命令
# 将this is a test line追加到以test开头的行的后面
sed '/^test/a\this is a test line' file

# 在test.conf文件第二行之后插入this is a test line
sed -i '2a\this is a test line' file
  1. 插入(行上):i\命令
# 将this is a test line 插入到以test开头的行的前面
sed '/^test/i\this is a test line' file

# 在第五行之前插入this is a test line
sed '5i\this is a test line' file
  1. 下一个:n命令
# 如果test被匹配,则移动到匹配行的下一行,替换这一行的aa,变为bb,并打印该行
sed '/test/{ n; s/aa/bb/; }' file
  1. 变形:y命令
# 把1-10行内所有的abcde转变为大写,注意,正则表达式元字符不能使用这个命令
sed '1,10y/abcde/ABCDE/' file
  1. 退出:q命令
sed '10q' file           # 打印完第十行后,退出sed
  1. 保持和获取:h命令和G命令

在sed处理文件的时候,每一行都被保存在一个叫模式空间的临时缓冲区中,除非行被删除或者输出被取消,否则所有被处理的行都将 打印在屏幕上。接着模式空间被清空,并存入新的一行等待处理

sed -e '/test/h' -e '$G' file
# 在这个例子里,匹配test的行被找到后,将存入模式空间,h命令将其复制并存入一个称为保持缓存区的特殊缓冲区内。
# 第二条语句的意思是,当到达最后一行后,G命令取出保持缓冲区的行,然后把它放回模式空间中,且追加到现在已经存在于模式空间中的行的末尾。
# 在这个例子中就是追加到最后一行。简单来说,任何包含test的行都被复制并追加到该文件的末尾。
  1. 保持和互换:h命令和x命令
sed -e 'test/h' -e '/check/x' file         # 把包含test与check的行互换
  1. 脚本scriptfile

sed脚本是一个sed的命令清单,启动Sed时以-f选项引导脚本文件名。Sed对于脚本中输入的命令非常挑剔,在命令的末尾不能有任何空白或文本,如果在一行中有多个命令,要用分号分隔。以#开头的行为注释行,且不能跨行。

sed [options] -f scriptfile file

  1. 打印奇数或偶数行
方法1:
sed -n 'p;n' test          # 奇数行
sed -n 'n;p' test          # 偶数行

方法2:
sed -n '1~2p' test         # 奇数行
sed -n '2~2p' test         # 偶数行
  1. 打印匹配字符串的下一行
grep -A 1 SCC URFILE
sed -n '/SCC/{n;p}' URFILE
awk '/SCC/{getline;print}' URFILE
  1. 匹配字符串, 并替换行

sed -i ‘/.*lang=JAVA*/c〈=RUST’ hello.txt

  1. 将第1-6行剪贴到第16行后

sed ‘1,6{H;d};16G’ test.txt

source

source FileName

在当前bash环境下读取并执行FileName中的命令。

*注:source命令也称为“点命令”,也就是一个点符号(.)。 source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录。该命令通常用命令“.”来替代。

source filename

. filename(中间有空格)

”,”“,“的各自用途

单引号是不能识别变量,只会原样输出,单引号是不能转义的 双引号能够识别变量,双引号能够实现转义(类似于“\”)

“:反引号(esc键下方的那个键),当在脚本中需要执行一些指令并且将执行的结果赋给变量的时候需要使用“反引号”。

例如:

#!/bin/bash
# Author: smile.
#Date & Time: 2021-08-04 16:30:27
#Description: output time.

str=`date +'%Y%m%d'`
echo $str

获得当前目录

1 . 获得shell脚本所在的绝对路径 CURRENT_DIR=$(cd $(dirname $0); pwd) 或者 CURRENT_DIR=$(cd `dirname $0`; pwd) 执行步骤解析: dirname $0: 取得当前执行的脚本文件所在的目录; cd: 进入当前工作目录; pwd: 显示当前工作目录; 将当前工作目录输出给变量CURRENT_DIR。

2 . 获得shell脚本所在目录的父级目录的绝对路径 由于能1 获得shell脚本所在的绝对路径,那么同理,就可以获得脚本所在目录的父级目录的绝对路径。 PARENT_DIR=$(cd $(dirname $0);cd ..; pwd) 只是在pwd命令之前添加了cd ..到父级目录。 注意: $()与“作用一样,用于shell命令的执行。 dirname: 显示最后一个结点前的路径;相对的,basename: 显示最后一个结点的名称。 $0: 脚本的路径名称,包含脚本本身的名称。

字符串截取

  1. 从字符串左边开始计数
格式 说明
${string: start :length} 从 string 字符串的左边第 start 个字符开始,向右截取 length 个字符。
${string: start} 从 string 字符串的左边第 start 个字符开始截取,直到最后。
${string: 0-start :length} 从 string 字符串的右边第 start 个字符开始,向右截取 length 个字符。
${string: 0-start} 从 string 字符串的右边第 start 个字符开始截取,直到最后。
${string#*chars} 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
${string##*chars} 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 右边的所有字符。
${string%*chars} 从 string 字符串第一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。
${string%%*chars} 从 string 字符串最后一次出现 *chars 的位置开始,截取 *chars 左边的所有字符。

如果想从字符串的左边开始计数,那么截取字符串的具体格式如下:

${string: start :length} 其中,string 是要截取的字符串,start 是起始位置(从左边开始,从 0 开始计数),length 是要截取的长度(省略的话表示直到字符串的末尾)。

例如:

url=”c.biancheng.net” echo ${url: 2: 9}

结果为biancheng。

再如:

url=”c.biancheng.net” echo ${url: 2} #省略 length,截取到字符串末尾

结果为biancheng.net。

  1. 从右边开始计数

如果想从字符串的右边开始计数,那么截取字符串的具体格式如下:

${string: 0-start :length} 同第 1) 种格式相比,第 2) 种格式仅仅多了0-,这是固定的写法,专门用来表示从字符串右边开始计数。

这里需要强调两点:

从左边开始计数时,起始数字是 0(这符合程序员思维);从右边开始计数时,起始数字是 1(这符合常人思维)。计数方向不同,起始数字也不同。 不管从哪边开始计数,截取方向都是从左到右。

例如:

url=”c.biancheng.net” echo ${url: 0-13: 9}

结果为biancheng。从右边数,b是第 13 个字符。

再如:

url=”c.biancheng.net” echo ${url: 0-13} #省略 length,直接截取到字符串末尾

结果为biancheng.net。

马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化