这篇主要是介绍行编辑器
sed和awk的使用,之前我们基本都有了解过vim编辑器,vim是以文件为模式的编辑器,主要是交互式,进入后需要使用命令来操作,例如:i
进入插入模式,wq
保存退出等;而sen和awk是非交互式的行操作;
sed
sed 一般用于对文本内容的替换;基本使用如下:
sed '/user1/s/user/u1' /etc/pwd
上面是一个替换指令s指令
,前面双斜线括起来的是正则表达式,其后面的也可以是正则表达式;
-
sed最常用最重要的作用就是去进行替换;
sed内部工作原理,模式空间处理
;- 将文件以行为单位读取到内存(模式空间);
- 使用sed的每个脚本对改行进行操作;
- 处理完成后输出此行;
-
替换命令
s
其最简单的使用如下:
sed 's/oldStr/newStr/' filename
上述命令的意思是使用newStr
字符串去替换oldStr
,注意两个字符都是被//
包裹,然后后跟要操作的文件;这里oldStr是可以使用元字符正则表达式进行替换;
我们桌面有一份日志文件如下:
#webrtcNative.log
[2022-06-07 10:33:39](peer_connection.cc:1117): (Initialize): start log record! old_allLogCount=0, old_infoLogCount=0, new_allLogCount=1, new_infoLogCount=1
[2022-06-07 10:33:39](peer_connection.cc:1126): hosten 1 (Initialize) configuration.isMutlClass = 1
[2022-06-07 10:33:39](peer_connection.cc:1128): hosten 2 (Initialize) ======================初始化多人===================
[2022-06-07 13:35:22][582:526] [39439] (RTCLogging.mm:35): (RTCNativeAudioSessionDelegateAdapter.mm:62 -[RTCNativeAudioSessionDelegateAdapter rtcAudioSessionDidChangeRoute:reason:previousRoute:]): Ignoring RouteConfigurationChange
[2022-06-07 13:35:22][582:617] [137663] (connection.cc:357): set_use_candidate_attr = 0
我们使用上述方式替换把06替换掉:sed 's/06/00012/' webrtcNative.log
或者简写sed 's/06/00012/;s/07/09/' webrtcNative.log
,执行后效果如下:
当然上述命令执行完成后源文件并不会被改变,如果需要替换后修改文件内容就需要-i
,使用方式如下:
注意:MacOS使用的是sed的BSD版本,它对-i选项的处理略有不同,所以下列是macOS的使用方式:sed -i "_back" 's/06/00012/;s/07/09/' webrtcNative.log
,其中"_back"
也可以是" "
,执行命令后就是在同目录下生成一个新的文件,如图:
打开后面的文件可以看到内容已经被修改成我们需要的;
- 多个替换
当需要替换多个的时候可以使用下列方式:
sed -e 's/oldStr/newStr/' -e 's/oldStr/newStr/' filename filname1 ...
sed -i 's/oldStr/newStr/' 's/oldStr/newStr/' filename filname1 ...
-i的含义是将替换的结果原样写回文件中;
多个替换命令-e的执行效果如下:
sed -e 's/06/00012/' -e 's/07/09/' webrtcNative.log
执行后:
可以看到文件中06-07
被两次替换成了00012-09
;
4. 正则替换
使用:sed 's/^\[/\{l/' webrtcNative.log
命令去替换亿[开头的,并且提花成{,执行后效果:
5. sed的替换命令加强版
* 全局替换:在s
命令的最后加上g
:'s/oldStr/newStr/g'
,用于替换所有出现的的次数;
* 标志位:'s/oldStr/newStr/标志位'
标志位是数字,代表出现第几次才替换;g,全部都替换;p,打印模式空间的内容;
* 寻址: 替换默认是对文件中所有行进行替换,增加寻址后可以对指定的行进行操作;正则s/oldStr/newStr/'
;
* 分组:寻址可以匹配多条命令,使用方式:/正则/{s/oldStr/newStr/;s/oldStr/newStr/}
;
* sed脚本文件:可以将sed的参数保存成文件 使用 -f
调用;sed -f secfile fileName
;
6. sed的其他命令
···
awk
awk 一般用于对文本内容进行统计、按照需要的格式进行输出;基本使用如下:
awk -F:'/wd$/{print $1}' /etc/password
1. 简介
一般用于比较规范的文本处理,用于统计数量并输出指定字段;
使用sed 将文本替换成比较规范的文本;
awk命令的使用,更贴近脚本语言;基本的控制流程如下:
输入数据以前执行的例程 BEGIN{};
主输入循环:{};
所有文件读取完成;
一般使用中不用把所有例程写完整,只写主循环就可以;
2. 字段引用和分离
- 记录:每一行称作记录
- 字段:使用空格,制表符分隔开的单次
- 可以自己指定分隔的字段;
字段引用方式: - awk中使用$1 $2 … $n表示每一个字段
awk'{ print $1, $2, $3}' filename
- awk可以使用-F选项改变字段分隔符
awk -F ',' '{ print $1, $2, $3}' filename
含义是使用 ,作为分隔符分隔字符串;
- 分隔符可以使用正则表达式
需要注意的是在shell脚本 $1表示命令函第一个参数,而在awk中$1表示第一个字段的内容;
需要注意的是如果字符总有中文需要设置成和文件一致的编码: export LANG='zh_CN.utf8'
;
基本使用如下:
上述示例是使用awk中使用正则去匹配[开头的内容;
使用-F分隔后获取第5个,如下:
含有中文的示例:
3. 表达式
- 赋值操作符:= 是常用的赋值符,等号的两边是可以有赋值符。如果有多个字符串使用空格分隔:
var1 = "name" var2 = "e" "f" var3=$1
其他的是有 ++、–、+=、…、^= 等;
-
算术运算符:+、-、*、/、%和^;
-
系统变量:
FS
和OFS
字段分隔符;OFS表示输出的字段分隔符;RS
字段分隔符;NR
和FNR
行数;NF
字段数量,获取最后一个字段内容可以使用$NF
;
-
关系操作符:<、>、<=、>=、== 、
!=
、~
、!~
;~
是正则表达式,用于正则; -
布尔操作符:
&&
,||
,!
4 流程语句
- if语句的使用和c很像,基本格式如下:
if(表达式)
awk语句
[else
awk语句
]
如果if中有多个语句需要执行,可以使用{}
括起来;
基本使用示例:
awk '{if($1>8) print $1}' wenjian.log
- while语句
while(表达式)
awk 语句
do
awk 语句
while(表达式)
基本使用:
5 数组
每一行的内容进行多行关联,就需要使用数组:
数组的定义如下:
arr[idx] = value
下标可以是数字也可以是字符串;
数组的遍历: for(变量 in arr)
,使用arr[i]的方式依次从数组中取出元素进行操作;
数组的删除:delete arr
; 删除数组的某个元素:deleta arr[idx]
命令行参数数组;ARGC
参数的个数;ARGV
参数的内容,在脚本文件使用如下:
# test.awk
BEGIN{
for(idx=0;idx<ARGC;idx++)
print ARGV[idx]
print ARGC
}
命令行执行:awk -f test.awk 99 88 77 44