Linux学习笔记(18)Linux sed,linux awk,linux grep,Linux三剑客
【1】sed
用法大全参考:https://blog.csdn.net/xiapang009/article/details/109194865
【1.0】基本语法
sed 's/原字符串/替换字符串/'
参数说明:
- -e<script>或--expression=<script> 以选项中指定的script来处理输入的文本文件。
- -f<script文件>或--file=<script文件> 以选项中指定的script文件来处理输入的文本文件。
- -h或--help 显示帮助。
- -n或--quiet或--silent 仅显示script处理后的结果。
- -V或--version 显示版本信息。
-
-r:使用扩展正则表达式
-
-e:它告诉sed将下一个参数解释为一个sed指令,只有当命令行上给出多个sed指令时才需要使用-e选项
-
-f:后跟保存了sed指令的文件
-
-i:直接对内容进行修改,不加-i时默认只是预览,不会对文件做实际修改
- -n:取消默认输出,sed默认会输出所有文本内容,使用-n参数后只显示处理过的行
动作说明:
- a :新增, a 的后面可以接字串,而这些字串会在新的一行出现(目前的下一行)~
- c :取代, c 的后面可以接字串,这些字串可以取代 n1,n2 之间的行!
- d :删除,因为是删除啊,所以 d 后面通常不接任何东东;
- i :插入, i 的后面可以接字串,而这些字串会在新的一行出现(目前的上一行);
- p :打印,亦即将某个选择的数据印出。通常 p 会与参数 sed -n 一起运行~
- s :取代,可以直接进行取代的工作哩!通常这个 s 的动作可以搭配正规表示法!例如 1,20s/old/new/g 就是啦!
单引号里面:
(1)s:表示替换
(2)3根斜线:他们中间是替换的样式,特殊字符需要使用反斜线”\”进行转义,但是单引号”‘”是没有办法用反斜线”\”转义的,这时候只要把命令中的单引号改为双引号就行了,例如:
(3)g:表示替换每一个匹配的关键字,否则只替换每行的第一个
sed "s/原字符串包含'/替换字符串包含'/" //要处理的字符包含单引号 sed 's?原字符串?替换字符串?' //自定义分隔符为问号 sed 's/^/添加的头部&/g' //在所有行首添加 sed 's/$/&添加的尾部/g' //在所有行末添加 sed '2s/原字符串/替换字符串/g' //替换第2行 sed '$s/原字符串/替换字符串/g' //替换最后一行 sed '2,5s/原字符串/替换字符串/g' //替换2到5行 sed '2,$s/原字符串/替换字符串/g' //替换2到最后一行
(4)多个sed 运行,以;为 分隔符
sed 's/^/添加的头部&/g;s/$/&添加的尾部/g' //同时执行两个替换规则
(5)文件内容替换
sed -i 's/原字符串/替换字符串/g' filename //替换文件中的所有匹配项
【1.1】sed替换文件中的内容
_6383 替换成 _6386
sed -i 's#_6383#_6386#g' redis_6386.conf
多个字符串替换,1.txt 中,1替换成a,2替换成b
sed -i 's#1#a#g;s#2#b#g' 1.txt
【1.2】删除文件中的第1行,删除文件文件中的3-5行
删除第一行 sed -i '1d' filename 删除第n行 sed -i 'nd' filename
删除最后一行 sed -i '$d' filename
删除3到5行
cat test.txt |sed '3,5d'
【1.3】删除字符串中的空格,删除空行 ,空格转换行
#删除行首空格 sed ‘s/^[ \t]*//g' #删除行末空格 sed ‘s/[ \t]*$//g' #删除所有空格 sed s/[[:space:]]//g
#空格开头的行
^\s+
#删除空行
sed '/^$/d'
#空格转换行
sed 's/ /\n/g '
【1.4】sed -n 获取某个字符串与某个字符串所在行之间的内容,某个字符串匹配行到文末
# 截取 fulldump.sql 文件中的 -- Current Database: `test` 到 下一个 -- Current Database: 任意值 这个区间中的行 sed -n '/^-- Current Database: `test`/,/^-- Current Database: `/p' fulldump.sql > test.sql
获取某个字符所在行到文末(文件末尾)
sed -n '/STRING/,$p' FILENAME
root@PC1:/home/test2# ls a.txt root@PC1:/home/test2# cat a.txt aa dd ss dd ff xv ef 33 cc xx ee ww df ff zc xx xx ff er ed ww xx xx ee er uy vv root@PC1:/home/test2# sed -n '/xx/,$p' a.txt ## 输出匹配xx至文末尾的行 xx ee ww df ff zc xx xx ff er ed ww xx xx ee er uy vv
【1.5】sed 行首行末添加字符
在每行的头添加字符,比如"HEAD",命令如下: sed 's/^/HEAD/g' test.file 在每行的行尾添加字符,比如“TAIL”,命令如下: sed 's/$/TAIL/g' test.file
删除行前4个字符
sed 's/....//g' test.file
【1.6】sed 插入一行数据到文件第一行、文件最后一行、文件第二行
sed -i '1s/^/set @@session.sql_log_bin=0;\n/g' ./*
# 把"hello"插入到第2行
sed -i '2i hello' sample.txt
# 把"hello"插入到最后一行
sed -i '$a hello' sample.txt
【1.7】 sed 删除某行到文件末尾,查找某个字符串所在行至文末
# 获取指定内容所在行号 row=`grep -n -i "c 5 7" test.txt |awk -F':' '{print $1}'` # 删除该行至文件末尾(删除内容包含该行) sed -i "${row},$d" test.txt
#sed '/123/,$d' 1.txt #删除从匹配123的行到最后一行
#sed -n '/STRING/,$p' FILENAME # 获取 STRING字符串所在行至文件末尾
【1.8】sed 删除1~2之外的所有行
sed '1,2!d' 1.txt #删除1~2之外的所有行
【1.9】sed 匹配有#号的行,然后操作
sed '/#/s/,.*//g' 1.txt #匹配有#号的行,替换匹配行中逗号后的所有内容为空 (,.*)表示逗号后的所又内容
sed -i '/=/s/$/&,/g' ${OUTPUT_TXT} # &号表示匹配的内容 $ 即行末,所以就是有等号的行的 行末添加逗号
案例:
sed -i '/220/s/^/-- &/g' t_settlementapply.sql # 所有的220所在行的行首,加-- 号
【1.10】sed 中的 &
sed -i '/=/s/$/&,/' ${OUTPUT_TXT} # &号表示匹配的内容 $ 即行末,所以就是有等号的行的 行末添加逗号 例如:sed 's#abc#&d#g' 1.txt # & 表示你前面匹配内容,就是 s 后面匹配的 abc ,文件本来是abc,执行前面那个就是abcd
【1.11】sed 删除指定字符串所在的行
#sed '/123/d' 1.txt #删除匹配123的行
【2】awk
【基本形式】awk
awk [选项参数] 'script' var=value file(s)
例如:
/sbin/ifconfig|grep -A1 -E "^eth0|em2"|grep "inet addr"|awk -F':' '{print $2}'
解析:
(1)awk -F 以:号为分隔符
(2)'{print $2}' 输出结果集的第2列
【2.1】获取IP地址
/sbin/ifconfig|grep -A1 -E "^eth0|em2"|grep "inet addr"|awk -F':' '{print $2}'|awk '{print $1}'
【2.2】把换行变成空格
find /data/mysql -type f \( -name "*.ibd" -o -name "*.MYD" \) -mmin -1440|awk -F "/" '{print $4}'|uniq|awk '{printf "%s ",$0}'
【2.3】awk求和、累计和
# 求总和 awk '{sum += $1}END{print sum}' a.txt #忽略第一行求和 awk -nr 'NR>=2 {sum+=$2}END{print sum}' a.txt # 求累计和 awk '{sum += $1}{print sum}' a.txt #在前一行和的基础上递增下一行的1/2 paste -d " " a.txt <(cat <(awk 'NR ==1 {print $0/2}' a.txt) <(awk '{sum+=$1}{print sum}' a.txt | sed '$d'))| awk '{print $0,$2 + $1/2}'
【2.4】awk获取最后1列,倒数第二列
#获取最后一列 cat 1-iplist.txt | awk '{ print $NF }' # 获取倒数第二咧
【2.5】awk获取多列,用逗号分隔
cat 1-iplist.txt | awk '{ print $1,$(NF-2) }'
【2.6】awk打印除第一列外的所有列
16s zcat ff.gz | awk '{x=2;while(x<=NF){printf "%s ", $x;x++;}printf "\n"}' > nice.txt ; 4s(最快,但是前面有空格-_-!): zcat ff.gz | awk '{$1 = null ;print}' > nice.txt 9min: zcat ff.gz | while read c1 c2 ; do echo c2; done > nice.txt ;
awk '{for(i=2;i<=NF;++i) printf $i "\t";printf "\n"}' test.txt
【2.7】获取奇数行
awk 'NR%2 != 0' a.txt
【内建变量】
$n | 当前记录的第n个字段,字段间由FS分隔 |
$0 | 完整的输入记录 |
ARGC | 命令行参数的数目 |
ARGIND | 命令行中当前文件的位置(从0开始算) |
ARGV | 包含命令行参数的数组 |
CONVFMT | 数字转换格式(默认值为%.6g)ENVIRON环境变量关联数组 |
ERRNO | 最后一个系统错误的描述 |
FIELDWIDTHS | 字段宽度列表(用空格键分隔) |
FILENAME | 当前文件名 |
FNR | 各文件分别计数的行号 |
FS | 字段分隔符(默认是任何空格) |
IGNORECASE | 如果为真,则进行忽略大小写的匹配 |
NF | 一条记录的字段的数目 |
NR | 已经读出的记录数,就是行号,从1开始 |
OFMT | 数字的输出格式(默认值是%.6g) |
OFS | 输出字段分隔符,默认值与输入字段分隔符一致。 |
ORS | 输出记录分隔符(默认值是一个换行符) |
RLENGTH | 由match函数所匹配的字符串的长度 |
RS | 记录分隔符(默认是一个换行符) |
RSTART | 由match函数所匹配的字符串的第一个位置 |
SUBSEP | 数组下标分隔符(默认值是/034) |
【3】grep
【3.0】基本语法
grep [-abcEFGhHilLnqrsvVwxy][-A<显示行数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...] 参数: -a 或 --text : 不要忽略二进制的数据。 -A<显示行数> 或 --after-context=<显示行数> : 除了显示符合范本样式的那一列之外,并显示该行之后的内容。 -b 或 --byte-offset : 在显示符合样式的那一行之前,标示出该行第一个字符的编号。 -B<显示行数> 或 --before-context=<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前的内容。 -c 或 --count : 计算符合样式的列数。 -C<显示行数> 或 --context=<显示行数>或-<显示行数> : 除了显示符合样式的那一行之外,并显示该行之前后的内容。 -d <动作> 或 --directories=<动作> : 当指定要查找的是目录而非文件时,必须使用这项参数,否则grep指令将回报信息并停止动作。 -e<范本样式> 或 --regexp=<范本样式> : 指定字符串做为查找文件内容的样式。 -E 或 --extended-regexp : 将样式为延伸的正则表达式来使用。 -f<规则文件> 或 --file=<规则文件> : 指定规则文件,其内容含有一个或多个规则样式,让grep查找符合规则条件的文件内容,格式为每行一个规则样式。 -F 或 --fixed-regexp : 将样式视为固定字符串的列表。 -G 或 --basic-regexp : 将样式视为普通的表示法来使用。 -h 或 --no-filename : 在显示符合样式的那一行之前,不标示该行所属的文件名称。 -H 或 --with-filename : 在显示符合样式的那一行之前,表示该行所属的文件名称。 -i 或 --ignore-case : 忽略字符大小写的差别。 -l 或 --file-with-matches : 列出文件内容符合指定的样式的文件名称。 -L 或 --files-without-match : 列出文件内容不符合指定的样式的文件名称。 -n 或 --line-number : 在显示符合样式的那一行之前,标示出该行的列数编号。 -o 或 --only-matching : 只显示匹配PATTERN 部分。 -q 或 --quiet或--silent : 不显示任何信息。 -r 或 --recursive : 此参数的效果和指定"-d recurse"参数相同。 -s 或 --no-messages : 不显示错误信息。 -v 或 --invert-match : 显示不包含匹配文本的所有行。 -V 或 --version : 显示版本信息。 -w 或 --word-regexp : 只显示全字符合的列。 -x --line-regexp : 只显示全列符合的列。 -y : 此参数的效果和指定"-i"参数相同。
【3.1】grep -E "str": 正则
【3.2】grep 出来的文件删除
(1)grep redis /etc/rc.local|sh
(2)cat /etc/rc.local |grep redis |xargs rm -f
【3.3】grep 出来的 linux 命令执行
cat /etc/rc.local |grep redis |xargs -i sh -c '{}' \;
单引号可加可不加,比如我 grep redis 出来的是这个
[root@bf-ltredis-1 ~]# cat /etc/rc.local |grep redis redis-server /data/redis/6383_redis/6383_redis.conf redis-server /data/redis/6384_redis/6384_redis.conf
【3.4】grep 获取目标行上下N行
如果想查看指定内容上下几行,可以用参考下面的用法:
$grep -10 ‘123’ test.log//打印匹配行的前后10行 或 $grep -C 10 ‘123’ test.log//打印匹配行的前后10行 或 $ grep -A 10 -B 10 ‘123’ test.log //打印匹配行的前后10行 $grep -A 10 ‘123’ test.log //打印匹配行的后10行 $grep -B 10 ‘123’ test.log//打印匹配行的前10行
其他例子:
//显示既匹配 ‘123’又匹配 ‘456’的行 grep ‘123’ test.log| grep ‘456’ //搜索test.log中满足123的内容的行号 grep -n ‘123’ test.log //查看test.log指定行号后的内容,比如50行 tail -n +50 test.log //查看test.log的第50行到100行 sed -n ‘50,100p’ test.log#记得p字母
【3.5】去除空行和注释行
grep -Ev "#|^$"
【4】综合运用
【4.1】匹配多个值 or | and
#同时匹配ABC 和 abc: sed -n '/ABC/{/abc/p}' awk '/ABC/&&/abc/{ print $0 }' grep -E '(ABC.*abc|abc.*ABC)' #匹配ABC 或 abc: sed -n '/\(ABC\|abc\)/p' awk '/ABC/||/abc/{ print $0 }' grep -E '(ABC|abc)' 或 egrep 'ABC|abc'
sed -i 's/原字符串/替换字符串/g' filename //替换文件中的所有匹配项
【5】其他小技巧
(5.1)空格转换行
tr ' ' '\n' sed 's/ /\n/g '