1.读取文件行
1.1 读取最后一行
awk 'END {print}'
sed -n '$p'
1.2 读取最后两行
sed '$!N;$!D'
awk '{b=a"\n"$0;a=$0}END{print b}'
2.判断
标识 |
意义 |
适用范围 |
-z “$str1” |
当串的长度为0时则为真 |
字符串 |
-n “$str2” |
当串的长度大于0时则为真 |
字符串 |
“$str1” |
当串为非空时则为真(与上等价) |
字符串 |
“$str1” = “$str2” |
当两个串有相同内容和长度时则为真 |
字符串 |
“$str1” == “$str2” |
当两个串有相同内容和长度时则为真(严格相等) |
字符串 |
“$str1” != “$str2” |
当两个串不等时则为真 |
字符串 |
“$str1” < “$str2” |
str1排序后在str2之前则为真 |
字符串 |
“$str1” > “$str2” |
str1排序后在str2之后则为真 |
字符串 |
“$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则为真 |
数字 |
-a FILE |
如果FILE存在则为真 |
文件 |
-b FILE |
如果FILE存在且是一个块特殊文件则为真 |
文件 |
-c FILE |
如果FILE存在且是一个字特殊文件则为真 |
文件 |
-d FILE |
如果FILE存在且是一个目录则为真 |
文件 |
-e FILE |
如果FILE存在则为真 |
文件 |
-f FILE |
如果FILE存在且是一个普通文件则为真 |
文件 |
-g FILE |
如果FILE存在且已经设置了SGID则为真 |
文件 |
-h FILE |
如果FILE存在且是一个符号连接则为真 |
文件 |
-k FILE |
如果FILE存在且已经设置了粘制位则为真 |
文件 |
-p FILE |
如果FILE存在且是一个名字管道则为真 |
文件 |
-r FILE |
如果FILE存在且是可读的则为真 |
文件 |
-s FILE |
如果FILE存在且大小不为0则为真 |
文件 |
-u FILE |
如果FILE存在且设置了SUID(set user ID)则为真 |
文件 |
-w FILE |
如果FILE存在且是可写的则为真 |
文件 |
-x FILE |
如果FILE存在且是可执行的则为真 |
文件 |
-O FILE |
如果FILE存在且属有效用户ID则为真 |
文件 |
-G FILE |
如果FILE存在且属有效用户组则为真 |
文件 |
-L FILE |
如果FILE存在且是一个符号连接则为真 |
文件 |
-N FILE |
如果FILE存在前且最后一次打开时被修改了则为真 |
文件 |
-S FILE |
如果FILE存在且是一个套接字则为真 |
文件 |
FILE1 -nt FILE2 |
如果FILE1比FILE2要新或者FILE1存在而FILE2不存在则为真 |
文件 |
FILE1 -ot FILE2 |
如果FILE1比FILE2要老或者FILE2存在而FILE1不存在则为真 |
文件 |
FILE1 -ef FILE2 |
如果FILE1和FILE2指向相同的设备和节点号则为真 |
文件 |
-t FD |
如果文件描述符FD打开且指向一个终端则为真 |
文件描述符FD |
-o OPTIONNAME |
如果shell选项”OPTIONNAME”开启则为真 |
shell |
-a |
与 |
逻辑 |
-o |
或 |
逻辑 |
! |
非 |
逻辑 |
-z “$str1”等类似情况一定要用双引号,不然会出现判断错误(这块可以多研究下各种情况下的表现)
3.区分操作系统
命令 |
结果(Mac) |
结果(Linux) |
uname |
Darwin |
Linux |
uname -a |
Darwin bogon 17.3.0 Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 x86_64 |
Linux 13c1548ff7bb 4.9.125-linuxkit #1 SMP Fri Sep 7 08:20:28 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux |
uname -m |
x86_64 |
x86_64 |
uname -n |
bogon |
13c1548ff7bb(容器ID) |
uname -p |
i386 |
x86_64 |
uname -r |
17.3.0 |
4.9.125-linuxkit |
uname -s |
Darwin |
Linux |
uname -v |
Darwin Kernel Version 17.3.0: Thu Nov 9 18:09:22 PST 2017; root:xnu-4570.31.3~1/RELEASE_X86_64 |
#1 SMP Fri Sep 7 08:20:28 UTC 2018 |
4.sed命令
4.1 删除
1.说明
# d标识为删除buffer
# 删除语法一般为
sed 'ADDRESS'd filename
sed /PATTERN/d filename
# 要删除的串可以用以下三种方式表示
nd(最后一行无法使用该形式,$d会报错,要加引号)
'nd'
'n'd
2.删除第n行
sed nd filename
3.从第n行开始,每隔m行删除(mac无法使用,m=0代表从第n行开始,直接删除到末尾)
sed n~m+1d filename
4.删除从第n行到第m行
sed n,md filename
5.删除最后一行($代表最后,使用$时一定要加引号,'$d'和'$'d都行,不加报错)
sed '$d' filename
6.行匹配删除(包含该字符串的所有行)
sed '/System/d' filename
7.删除从匹配行到末尾
sed '/System/,$d' filename
8.删除匹配行之后n行(匹配行也算在n之内,mac无效,无论n多大,只会删除匹配行)
sed '/System/,+nd' filename
9.清除空行
sed '/^$/d' filename
10.正则删除
sed '/System.*/d' filename
11.对原文件生效
加-i才可以对文件进行真正的更改
4.2 插入
# 从第n行后添加内容
1.linux系统
# 直接添加一行,之后的行会下移
# 方式一(一定要单引号,双引号不支持)
sed -e na\\'newLine String\' filename
# 方式二
sed -e 'na newLine String' filename
2.mac系统
# 内容会新起一行,但之前的行内容不会下移一行,而是会放在新插入内容之后
sed 'na\'$'\n''newLine String' filename
# 在n行前插入,之前的内容不会下移一行,而是会放在新插入内容之后
sed 'ni\'$'\n''newLine String' filename
# a与i的区别在于i在n行首插入,并挤压原内容,而a在n行后新起行插入,并挤压n行下一行内容
4.3 修改
1.把world1改成world0,s表示替换,g表示全局(这里有没有g效果一样)
sed "s/world1/world0/" filename
2.把第2行,第4行所有的hello替换为welcome
sed "2,4s/hello/welcome/" filename
3.找到world3所在行,把所有的hello替换为welcome(不加g只会替换第一个)
sed "/world3/s/hello/welcome/g" filename
4.正则匹配修改,把所有的world+一个数字改成beijing(不加g则world10及以上都不会匹配到,而加g则会匹配到,world10->bejing0,world11->beijing1)
sed "s/world[0-9]/beijing/g" filename
5.变量 \(.*\)会匹配出一个变量,\1表示第一个变量,\2表示第二个变量,以下相当于交换-符号左右两边字符的位置
sed "s/\(.*\)-\(.*\)/\2-\1/g" filename
6.把2-5行替换为字符串China(第6行会紧接着China)
sed '2,5c\'$'\n''China' filename
4.4 查看
# p打印buffer(记得使用时加上-n选项)
1.查看最后一行内容
sed -n '$p' filename
2.查看第一行内容
sed -n '1p' filename
3.查看第一行到第二行内容
sed -n '1,3p' filename
4.查看所有包含beijing所在的行
sed -n '/beijing/p' filename
4.5 读取和写入数据
1.把filename2的内容放在filename1的第一行之后(另起一行,内容添加完比后再另起一行接原内容),r进行读取写入filename1,返回修改过后的filename1,filename2保持不变
sed "1r filename2" filename1
2.把filename1的第一行内容覆盖写入到filename2,返回filename1无变化,查到filename2只有filename1的第一行,可衍生出5.3
sed "1w filename2" filename1
3.把filename1的第3-5行数据,写入到filename2中
sed "3,5w filename2" filename1
4.6 平台差异
# sed命令在mac系统中和linux系统中表现不一样,具体为第1点删除时的1.3和1.7中表现,另外1.10对文件生效处理方式也不一样
1.mac系统
# -i后面强制要接备份文件,如果不想备份,直接写''即可,写了备份文件名称,则生成的完整备份文件名为filenamebackfilename,连文件后缀也连在一起
sed -i backfilename '$d' filename
2.linux系统
sed -i '$d' filename