Linux三剑客学习笔记

8 篇文章 0 订阅

正则表达式

学习三剑客之前我们首先要了解正则表达式,有了它能让你更强大。正则表达式在每种语言中都会有,功能就是匹配符合你预期要求的字符串。

符号说明示例
.匹配除换行符(\n)之外的任意单个字符匹配123:echo -e “123\n456” | grep ‘1.3’
^匹配以字符串开头匹配以abc开头的:echo -e “adb\nabcd” | grep ^abc
$匹配以字符串结尾匹配以adb结尾的:echo -e “adb\nabcd” | grep bcd$
*匹配前一个字符0个或多个匹配 x、xo 和 xoo:echo -e “x\nxo\nxoo\no\noo” | grep "xo*"x 是必须的,批量了 0 个或多个
+匹配前面字符一个或多个匹配 abc 和 abcc:echo -e “abc\nabcc\nadd” |grep -E 'ab+'
匹配单个数字:echo “113” |grep -o '[0-9]'
连续匹配多个数字:echo “113” |grep -E -o ‘[0-9]+’
?匹配前面字符0个或一个匹配abc或bcd:echo -e “ac\nabc\nad\nbcd” | grep -E ‘bc?’
[]匹配括号中任意一个字符匹配bch:echo -e “ab\ncd\nef\nhg\nlk” | grep -o ‘[bch]’
[ - ]匹配括号中范围的任意一个字符匹配所有字母: echo -e “ab\ncd\nef” | grep -o ‘[a-z]’
[^]匹配除括号中的字符之外的任意一个字符匹配除m、n、o之外的字符:echo -e “and\nor\nnot” | grep -o '[^m-o]'
匹配末尾数字:echo “abc:cde;123” | grep -E ‘[^;]+$’
^[^]匹配不是中括号之内任意一个字符开头的行匹配非s开头的:echo -e “sho\nkst\nabc\ntest” | grep ‘^[^s]’
{n}或{n,}匹配花括号前面的字符至少n个字符匹配任意至少2个字符以上的字符串:echo -e “a\nac\nadc\nnc” | grep -E ‘[a-z]{2}’
{n,m}匹配花括号前面至少n个字符,最多m个字符匹配任意至少2个字符以上的字符串:echo -e “a\nac\nadc\nnc” | grep -E -w -o ‘[a-z]{1,2}’
\<边界符,匹配字符串开始匹配以123开始的:echo -e “1\n\12\n123\n1234” | grep ‘<123’
\>边界符,匹配字符串结束匹配以4结束的:echo -e “1\n\12\n123\n1234” | grep ‘4>’
()单元或组合:将小括号里面作为一个组合
分组:匹配小括号中正则表达式或字符。\n反向引用,n是数字,从1开始编号,表示引用第n个分组匹配的内容
单元:匹配123a字符串
echo “123abc” | grep -E -o '([0-9a-z]){4}'
分组:匹配11
echo “113abc” \I grep -E -o '(1)\1’
匹配xo出现0次或多次:
echo -e “x\n\xo\nxoo\no\noo” | egrep “(xo)*”
|匹配竖杠两边的任意一个匹配12和123:
echo -e “1\n\12\n123\n1234” | grep -E ‘12>| 123>’
\转义符,将特殊符号转成原有意义1.2匹配1.2 :
echo -e “1.2\n112” | grep -E ‘1\.2’ 否则112也会匹配到

grep

grep是global search regular expression and print out the line的缩写,意思是全面搜索正则表达式并把行打印出来,是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来。

常用参数

参数说明
-a 或 --text不要忽略二进制的数据。
-A<显示行数>除了显示符合样本的那行,并显示之后的N行
-B<显示行数>除了显示符合样本的那行,并显示之前的N行
-b 或 --byte-offset在显示符合样式的那行之前,标示出该行第一个字符的编号
-c 或 --count计算符合样式的列数
-C 或 --context=<显示行数> 或-<显示行数>除了显示符合样式的那行,并显示该行前后的内容
-d 或 --directories=<动作>当指定要查找的是目录而非文件时,必须使用这项参数,否则 grep 命令将回报信息并停止动作
-e <范本样式> 或 --regexp=<范本样式>指定字符串作为查找文件内容的样式
-E 或 --extend-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 或 --revert-match显示不包含匹配文本的所有行
-V 或 --version显示版本信息
-w 或 --word-regexp只显示全字符合的列
-x 或 --line-regexp只显示全列符合的列
-y此参数的效果和指定 “-i” 参数相同

语法

grep [-abcEFGhHilLnqrsvVwxy][-A<显示列数>][-B<显示列数>][-C<显示列数>][-d<进行动作>][-e<范本样式>][-f<范本文件>][--help][范本样式][文件或目录...]

实例

我们新建个文件,内容如下

# 文件名称为lucky.sh
list=$(while read line; do echo ${line}; done<10.wx)
count=0;
index=0;
while ((count!=1))
do
    ((index+=1));
    temp=$list
    list=$(for i in $list;do ((RANDOM%2==1)) && echo $i; done);
    echo;
    cout=$(echo "$list" | wc -w);
    if [ $cout -eq 0 ]
    then
    while ((cout==0))
    do
        echo "此次抽奖结果为空,继续抽奖!"
        list=$(for i in $temp;do ((RANDOM%2==1)) && echo $i; done );
        cout=$(echo "$list" | wc -w);
        echo The $index times:$list;
    done
    else
    echo The $index times:$list;
    fi
    count=$(echo "$list" | wc -l);

DONE

假设我们想从文件中搜索包含done字符串的行,可以使用如下命令:

grep done lucky.sh
# 输出显示为
list=$(while read line; do echo ${line}; done<10.wx)
    list=$(for i in $list;do ((RANDOM%2==1)) && echo $i; done);
        list=$(for i in $temp;do ((RANDOM%2==1)) && echo $i; done );
    done

发现最后一行大写的DONE没有被打印出来,这是因为grep是默认区分大小写的,如果想要在搜索时不区分大小写,使用 -i 即可,如下:

grep -i done lucky.sh

如果我们想要知道包含 done 是哪些行,可以用如下命令:

grep -i -n done lucky.sh 
或
grep -in done lucky.sh
# 输出结果为
1:list=$(while read line; do echo ${line}; done<10.wx)
8:    list=$(for i in $list;do ((RANDOM%2==1)) && echo $i; done);
16:        list=$(for i in $temp;do ((RANDOM%2==1)) && echo $i; done );
19:    done
25:DONE

想知道总共有多少行符合,需要使用 -c,如下:

grep -c done lucky.sh 
# 输出为
5

PS:此时如果和 -i 一起使用是不会打印出所有行的,只会统计行数。
如果只想展示搜索内容时,使用参数-o,使用方法如下:

grep -o done lucky.sh
# 输出结果如下
done
done
done
done

如果想显示样式之后的几行,需要用 -A 行数;显示之前的行数,需要用 -B 行数;显示前后的行数,需要用 -C 行数;如果想要精确匹配,需要使用参数-w,如下:

-------------------------------------------
# 新建文件testgrep
hello test
hellotest
nello
Hello test
HELLOtest
www.hellotest.com
123hello
hello456test
time456
---------------------------------------------
# 模糊匹配
grep hello testgrep
# 输出结果为
hello test
hellotest
www.hellotest.com
123hello
hello456test
---------------------------------------------
# 精确匹配
grep -w hello testgrep
# 输出结果为
hello test

PS:我们会发现只有上搜索样式作为独立的单词才会被匹配到。
如果要反向匹配,需要使用参数-v,如下:

grep -v hello testgrep
# 输出结果为
Hello test
HELLOtest

如果想要根据多个字符串匹配,需要使用-e,如下

grep -e 123 -e time testgrep
#  输出结果为
123hello
time456

PS:通过实例我们发现,只要匹配到一个条件的就会打印。
如果你只是想用grep判断文本中是否存在某个字符串,你只关心有没有匹配到,而不关心匹配内容,这时我们可以使用-q进行静默匹配,需要配合“echo $?”使用,实例如下:

grep -q hello testgrep
echo $?
# 输出结果为
0 表示匹配到了 /  1 表示没有匹配到

匹配所有IP

ifconfig | grep -E -o "[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}\.[0-9]{1-3}"

--------------------------------敲黑板,重点来了--------------------------------

利用 [ ] 搜索集合字符,[ ] 表示其中的一个字符,例如

grep '[aci]' testgrep
# 输出结果为
www.hellotest.com
time456

如果想要查找除 [] 内之外的字符,可以用 [^ 字符],比如匹配非n开头包含e的字符串,例如

grep -n [^n]e testgrep
# 输出结果为
1:hello test
3:hellotest
4:Hello test
6:www.hellotest.com
7:123hello
8:hello456test

[] 还可以用范围表示,如[0-9]表示0~9的数字,[a-z]表示26个字母,[0-9a-z]表示任意数字字母

awk

awk是一种处理文本文件的语言,能用简短的程序处理标准输入或文件、数据排序、计算以及生成报表等等。

参数

参数说明
-F fs指定fs为输入字段的分隔符
-f file从文件中读取awk程序源文件
-v var=value变量赋值
–posix兼容posix正则表达式
–dump-variables=[file]把 awk 命令时的全局变量写入文件,默认文件是 awkvars.out
–profile=[file]格式化 awk 语句到文件,默认是 awkprof.out
模式描述
BEGIN{}给程序赋予初始状态,先执行的工作
END{}程序结束之后执行的一些扫尾工作
/regular expression/为每个输入记录匹配正则表达式
pattern && pattern逻辑与,满足两个模式
pattern || pattern逻辑o或,满足其中一个
! pattern逻辑非,不满足模式
pattern1, pattern2范围模式,匹配所有模式1的记录,知道匹配到模式2
$0表示一整行数据
$n表示第n列
NF每一行拥有的字段总数
NR目前处理的是第几行数据
FS分隔符

实例

# 新建文本 awk.txt
1 hello welcome to awk
3 sdf sldkjk  slkdj jklkl lkj
6 skd wer lx sdf sada
8 sdfa afg
2 sdflk
4 sdflkak  sldkjflk  iualj sada                              

打印第二列和第五列的数据

awk '{print $2,$5}' awk.txt
# 输出
hello awk
sdf jklkl
skd sdf
sdfa 
sdflk 
sdflkak sada

打印行数内容及行数、行字段总数

awk '{print "该行数据为" $0 "\t" "该行的字段总数为" NF "\t" "目前这是第几行" NR }' awk.txt 
# 输出
该行数据为1 hello welcome to awk	该行的字段总数为5	目前这是第几行1
该行数据为3 sdf sldkjk  slkdj jklkl lkj	该行的字段总数为6	目前这是第几行2
该行数据为6 skd wer lx sdf sada	该行的字段总数为6	目前这是第几行3
该行数据为8 sdfa afg	该行的字段总数为3	目前这是第几行4
该行数据为2 sdflk	该行的字段总数为2	目前这是第几行5
该行数据为4 sdflkak  sldkjflk  iualj sada	该行的字段总数为5	目前这是第几行6

设置变量

awk -v a=2 '{print $1,$1+a}' awk.txt
#  输出 
1 3
3 5
6 8
8 10
2 4
4 6

打印奇数行第二列

awk  'NR % 2 == 1 {print "行数为" NR "\t" $2} ' awk.txt
# 输出
行数为1	hello
行数为3	skd
行数为5	sdflk

使用条件语句打印第二行之后的数据

awk '{if(NR>1) print $2}' awk.txt
# 输出
sdf
skd
sdfa
sdflk
sdflkak

sed

sed是一种流编辑器,用来过滤和替换文本。

参数

参数说明
a新增,a的后面可以接字符串,而这些字符串在新的一行出现(当前行的下一行)
d删除选择的行
-e<script>以选项中指定的script来处理输入的文本文件
-f<script>以选项中指定的script来处理输入的文本文件
g全局替换标志。默认情况下,sed 命令替换每一行第一次出现的模式,它不会替换行中的其他的匹配结果。但是,提供了该替换标志时,所有匹配都将被替换。
-h显示帮助
i插入,i的后面可以接字符串,而这些字符串会在新的一行出现(当前行的上一行)
-n或–quiet或–silent仅显示script处理后的结果
s替换指定字符,通常与正则联用
-V显示版本信息

实例

# 新建样本 sed.txt
This is my cat
  my cat's name is betty

This is my dog
  my dog's name is frank

This is my fish
  my fish's name is george

This is my goat
 my goat's name is adam

  • 插入
sed -i "3i\test123" sed.txt
# 输出为
This is my cat
  my cat's name is betty
test123

This is my dog
  my dog's name is frank

This is my fish
  my fish's name is george

This is my goat
 my goat's name is adam

  • 新增
sed -i "3a\test456" sed.txt
# 输出为
This is my cat
  my cat's name is betty
test123
test456

This is my dog
  my dog's name is frank

This is my fish
  my fish's name is george

This is my goat
 my goat's name is adam
  • 替换
sed "s/my/hogward's/g" sed.txt
# 输出结果为
This is hogward's cat
  hogward's cat's name is betty

This is hogward's dog
  hogward's dog's name is frank

This is hogward's fish
  hogward's fish's name is george

This is hogward's goat
 hogward's goat's name is adam
  • 输出
# 输出文件所有内容
sed -n '1,$p' /etc/hosts
# 将每行内容放到一行上进行展示,每行内容以逗号进行分隔。
sed ':t;N;s/\n/,/;b t' /etc/hosts
# 输出第二行到第四行之间三行的内容
sed -n "2,4p" /etc/hosts
  • 删除
sed '/test123/d' sed.txt
# 输出为
This is my cat
  my cat's name is betty
test456

This is my dog
  my dog's name is frank

This is my fish
  my fish's name is george

This is my goat
 my goat's name is adam
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值