linux四剑客find、grep、sed、awk

Linux高级命令

  • find:常用在目录下精确查找文件(最擅长找文件)
  • sed:常用来做行数据增删改查(最擅长取行)
  • awk:常用来做列数据切分与提取(最擅长取列)
  • grep:常用来做全局数据的查询定位(最擅长文本过滤)

1.find【擅长找文件】

1.1 find语法

语法:find path -option [ -print ][ -exec -ok command ] {} ;

1.2 常用查询选项option

-name: 根据名称匹配

-iname: 忽略大小写

-user: 根据所属与的组进行查询

# 例如:查找根目录下以log为结尾的文件:
$ find / -name '*log'
# 例如:查当前路径下,属于sichuan的文件:
$ find . -user sichuan

-group: 根据文件所属组进行查询

-type: 根据类型进行查找

  • f 文件
  • d 目录

-size: 根据文件大小匹配

  • -n 小于 大小为 n 的文件
  • +n 大于 大小为 n 的文件
# 查找 /ect 目录下,小于 10000 字节的文件
$ find /etc -size -10000c
# 查找 /etc 目录下,大于 1M 的文件
$ find /etc -size +1M

-mindepth n: 从第 n 级目录开始搜索

# 从 /etc 的第三级子目录开始搜索
$ find /etc -mindepth 3 -name '*.conf'

-maxdepth n: 表示至多搜索到第 n-1 级子目录

# 在 /etc 中搜索符合条件的文件,但最多搜索到 2级 子目录
$ find /etc -type f -name '*.conf' -size +10k -maxdepthc 2

时间戳查询选项option

UNIX/Linux文件系统每个文件都有三种时间戳

  • 访问时间 (-atime/天,-amin/分钟):用户最近一次访问时间。
  • 修改时间 (-mtime/天,-mmin/分钟):文件最后一次修改时间。
  • 变化时间 (-ctime/天,-cmin/分钟):文件数据元(例如权限等)最后一次修改时间。

注意:

  • -n :n 天/分钟 以内
  • +n :n 天/分钟 以外
  • n :正好 n天/分钟

按修改时间查询案例

# 查询 /etc 目录下 30分钟 之前修改过的文件
$ find /etc -mmin +30

# 查询 /etc 目录下 30分钟 之内修改过的目录
$ find /etc -mmin -30 -type d

# 查询 /etc 目录下,5天以内修改 且以 conf 结尾的文件
$ find /etc -mtime -5 -name '*.conf'

# 查询 /etc 目录下,10天之前修改,且属于 sichuan账户的文件
$ find /etc -mtime +10 -user sichuan

# 找出比file.log修改时间更长的所有文件
find . -type f -newer file.log

按访问时间查询案例

# 搜索最近七天内被访问过的所有文件
$ find . -type f -atime -7

# 搜索恰好在七天前被访问过的所有文件
$ find . -type f -atime 7

# 搜索超过七天内被访问过的所有文件
$ find . -type f -atime +7

# 搜索访问时间超过10分钟的所有文件
$ find . -type f -amin +10

1.3 对查找到的文件如何操作

find语法中:-print 和 -exec

-print:打印输出。 默认的选项,即打印出找到的结果。

**-exec:**对搜索到的文件执行特定的操作,固定的格式为:-exec ‘commond’ {} ; 注意:{} 表示查询的结果。

# 搜索 /etc 目录下的文件(非目录),文件以 conf 结尾,且大于 10k,然后将其删除
$ find /etc -type f -name '*.conf' -size +10k -exec rm -f {} \

# 搜索条件同 例1 一样,但是不删除,只是将其复制到 /root/conf 目录下
$ find /etc -type f -name '*.conf' -size +10k -exec cp {} /root/conf/ \;

# 将 /data/log/ 目录下以 .log 结尾的文件,且更改时间在 7 天以上的删除
$ find /data/log -name '*.log' -mtime +7 -exec rm -f \

-ok-exec 的功能一样,只是每次操作都会给用户提示。

逻辑运算符

-a:与 (默认情况查询条件之间都是 与 的关系)

-o:或

-not | ! 非

1.4 常用操作

🚩xargs: 可以将一个命令的输出作为参数发送给另一个命令。

当前目录搜索所有文件,文件内容 包含 “aaa” 的内容

find . -type f -name "*" | xargs grep "aaa"
./a.txt:aaa
./b.txt:aaa

代码行数统计, grep -v '^$'过滤空白行 wc -l

$ find . -name "*.java"|xargs cat|grep -v ^$|wc -l 

统计关键词出线的次数

$ cat /proc/meminfo |grep Swap | wc -l

基于正则表达式匹配文件路径(-iregex忽略大小写)

$ find . -regex ".*\(\.txt\|\.pdf\)$"

查找当前目录下所有.txt文件并把他们拼接起来写入到all.txt文件中

$ find . -type f -name "*.txt" -exec cat {} \;> /all.txt

将30天前的.log文件移动到old目录中

$ find . -type f -mtime +30 -name "*.log" -exec cp {} old \;

找出当前目录下所有.txt文件并以“File:文件名”的形式打印出来

$ find . -type f -name "*.txt" -exec printf "File: %s\n" {} \;

因为单行命令中-exec参数中无法使用多个命令,以下方法可以实现在-exec之后接受多条命令

$ -exec ./text.sh {} \;

要列出所有长度为零的文件

$ find . -empty

2.grep【擅长文本过滤】

grep命令 是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配的行打印出来(匹配的标红)

2.1 grep语法

语法:grep [option] pattern file

2.2 grep命令参数

  • -A<显示行数>:除了显示符合范本样式的那一列之外,并显示该行之后的内容
  • -B<显示行数>:除了显示符合样式的那一行之外,并显示该行之前的内容
  • -C<显示行数>:除了显示符合样式的那一行之外,并显示该行之前后的内容
  • -c:统计匹配成功的行数
  • -e :实现多个选项间的逻辑or 关系 。或者使用egrep
  • -E:扩展的正则表达,相当于egrep
  • -f FILE:从FILE获取PATTERN匹配
  • -F :相当于fgrep
  • -l:列出文件内容符合指定的范本样式的文件名称。
  • -L:列出文件内容不符合指定的范本样式的文件名称
  • -i :字符忽略大小写
  • -n:显示匹配的行号
  • -o:仅显示匹配到的字符串
  • -q: 静默模式,不输出任何信息
  • -s:不显示错误信息。
  • -v:显示不被pattern 匹配到的行,相当于[^] 反向匹配
  • -w :只匹配整个单词,而不是字符串的一部分(如匹配’magic’,而不是’magical’),
  • –color:匹配到的关键字会高亮显示
  • \< 和 \> 分别标注单词的开始与结尾。
    • grep man * 会匹配 ‘Batman’、’manic’、’man’等
    • grep ‘\<man’ * 匹配’manic’和’man’,但不是’Batman’
    • grep ‘\<man\>’ 只匹配’man’,而不是’Batman’或’manic’等其他的字符串
    • 查询关键字高亮显示:grep xxx --color=auto

实例:

$ cat test 
aaa
bbbbb
AAAaaa
BBBBASDABBDA

# 显示结果及前后各1行的数据
$ grep -C1 b test
aaa
bbbbb
AAAaaa

# 统计行数
$ grep -c aaa test
2

# 实现多个逻辑 or 或
$ grep -e AAA -e bbb test
bbbbb
AAAaaa

# 忽略大小写并显示行号
$ grep -in b test
2:<font color='red'>bbbbb</font>
4:BBBBASDABBDA

# 仅显示匹配到的字符串
$ grep -o ASDA test
ASDA

# 静默模式,不显示
$ grep -q aa test

# 取反
$ grep -v aaa test
bbbbb
BBBBASDABBDA

# 匹配整个单词
$ grep -w aaa
aaa

# 从file获取PATTERN匹配
$ cat grep.txt
aaa
$ grep -f grep.txt test
aaa
AAAaaa

# 使用-l选项,找出文件内容中包含first的文件名
$ grep -l "first" *.txt
1.txt

# 使用-L选项,找出文件内容中不包含first的文件名
$ grep -L "first" *.txt
2.txt
3.txt

# 以leo开头的行
$ grep '^leo' /etc/passwd

# 以bash结尾的行
$ grep 'bash$' /etc/passwd

# 我们尝试匹配bin这个“词”(只包含bin 比匹配sbin这样的)在正则表达式中,我们通常用尖括号表示一个“词”
$ grep '\<bin\>' /etc/passwd --color

# 查找xxx目录下所有文件带abc的行
$ grep abc /home/sichuan/lihewei/project/daquhua/getMd5Info/*
/home/sichuan/xxx/project/abc/a.txt:abc123
/home/sichuan/xxx/project/abc/b.txt:abcd123

grep、cat、管道符配合使用

$ cat test.txt |grep hello  # |管道符,将一个命令的输出作为另外一个命令的输

grep、ps、管道符配合使用

$ ps -ef|grep ssh|grep -v grep  #过滤ssh进程信息,并去除最后一行的grep信息

检索日志,并显示该条日志的前后N(10)行记录

$ cat 日志文件 | grep -n -C10 "关键字"

3.sed【擅长对行操作】

​ sed 是一种流编辑器,它一次处理一行内容。处理时,把当前处理的行存储在临时缓冲区中,称为**“模式空间”**,接着用 sed 命令处理缓冲区中的内容,处理完成后,把缓冲区的内容送往屏幕。

简介:常用来做行数据增删改查(最擅长取行)

3.1 sed语法

格式:sed [option]... 'script' inputfile

翻译:sed [选项] [脚本命令] 文件名

3.2 option选项

  • -n 不输出模式空间内容到屏幕,即不自动打印
  • -e 多点编辑
  • -f /PATH/SCRIPT_FILE: 从指定文件中读取编辑脚本
  • -r 支持使用扩展正则表达式
  • -i 直接编辑文件(慎用)
  • -i.bak 备份文件并原处编辑

3.3 script地址选择

(指定第几行)

  1. 不给地址:对全文进行处理

  2. 单地址:
    #:指定的行

    $:最后一行
    /pattern/:被此处模式所能够匹配到的每一行

    /abc/, +1:匹配abc及后面一行

  3. 地址范围:
    #,#
    #,+#
    /pat1/,/pat2/
    `#,/pat1/

  4. ~:步进
    1~2 奇数行
    2~2 偶数行

3.3 编辑命令

  • d 删除模式空间匹配的行,并立即启用下一轮循环
  • p 打印当前模式空间内容,追加到默认输出之后(匹配成功的内容追加到文本最后)
  • a []text1 在指定行后面追加文本,支持使用\n实现多行追加
  • i []text 在行前面插入文本
  • c []text 表示把选定的行改为新的文本
  • w /path/somefile 保存模式匹配的行至指定文件
  • r /path/somefile 读取指定文件的文本至模式空间中匹配到的行后
  • = 为模式空间中的行打印行号
  • ! 模式空间中匹配行取反处理
  • s///:查找替换,支持使用其它分隔符,s@@@,s###

3.4 s/// 替换脚本命令

格式:sed '[address-range|pattern-range] s/original-string/replacement-string/[substitute-flags]' inputfile;

解释:

  • address-range:地址列表,表示从哪个地方开始执行,如:1,3 表示第一行到第 3 行;

  • pattern-range:样式列表,表示从哪个样式匹配串开始。如:/Jane/,表示从行中包含字符串 Jane 的行开始执行,[ ]中的都是可选的

  • s:表示要执行替换命令(substitute);

    • originalstring:需要被替换的字符串 ;
    • replacement-string:替换后的字符串;
    • substitute-flags:可选替换标志符;
  • d表示删除

  • $表示行尾

  • ^表示开头

  • \s空白符正则

  • \s*表示连续空格的字符串

  • address-range 和 pattern-range (匹配位置)

3.4.1 s脚本全局标记
  • 数字 1~512 同一行中第几次出现,例如s/a/x/2,能匹配上的只有 aaa 中间的a,数字代表第二次出现
  • g 行内全局替换(否则只操作行内第一次匹配到的字符)
  • p 显示替换成功的行
  • w /PATH/TO/SOMEFILE 将替换成功的行保存至文件中
  • & 用正则表达式匹配的内容进行替换;
  • \n 匹配第 n 个子串,该子串之前在 pattern 中用 () 指定。
  • \ 转义(转义替换部分包含:&、\ 等)。

语法:sed '[address-range|pattern-range] s/original-string/replacement-string/[substitute-flags]' inputfile;

[substitute-flagsa] g 行内全局替换

# 查看某段时间内的日志:sed -n '/起始时间/,/结束时间/p' 日志文件
$ sed -n ‘/2018-06-21 14:30:20/,/2018-06-21 16:12:00/p’ log.txt | grep ‘keyword’
匹配位置

address-range 和 pattern-range (匹配位置)

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#1. address-range 和 pattern-rangea> 把第一行的 John 替换成 lili 字符串
$ sed '1 s/John/lili/' example.txt
101,lili Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#2. 把第2行至第5行的 Manager 替换成 lili
$ sed '2,5 s/Manager/lili/' example.txt
101,John Doe,CEO
102,Jason Smith,IT lili
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler lili

#3. 把 John 所在字符串行当中的 CEO 替换成 XXX
$ sed '/John/ s/CEO/XXX/' example.txt
101,John Doe,XXX
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#4. 从第四行而且包含字符串 Ram 的行中,把 Developer 字符串替换成 XXX
$ sed '4,/Ram/ s/Developer/XXX/' example.txt
101,John Doe,XXX
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#5. 如果没有 address-range 和 pattern-range,那么就会把每一行碰到的第一个匹配字符串给替换掉
$ sed 's/1/AAA/' example.txt
AAA01,John Doe,CEO
AAA02,Jason Smith,IT Manager
AAA03,Raj Reddy,Sysadmin
AAA04,Anand Ram,Developer
AAA05,Jane Miller,Saler Manager

# -n 选项会禁止 sed 输出,但 p 标记会输出修改过的行
$ cat data5.txt
This is a test line.
This is a different line.
$ sed -n 's/test/trial/p' data5.txt
This is a trial line.

# w 标记会将匹配后的结果保存到指定文件中
$ sed 's/test/trial/w test.txt' data5.txt
This is a trial line.
This is a different line.
$ cat test.txt
This is a trial line.

# 用文本模式指定行区间,
$ grep demo /etc/passwd
demo:x:502:502::/home/Samantha:/bin/bash
# 用正斜线将要指定的 pattern 封起来,sed 会将该命令作用到包含指定文本模式的行上。
$ sed '/demo/s/bash/csh/' /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
demo:x:502:502::/home/demo:/bin/csh
...
s命令全局标记 数字

数字标志 1,2,3 把要匹配串中的第 n 个符合条件的匹配串替换成我们想要的字符串

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# 数字标志 1,2,3 把要匹配串中的第 n 个符合条件的匹配串替换成我们想要的字符串
$ sed 's/1/AAA/2' example.txt
10AAA,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager
全局标记 g

全局标志会把遇到的所有的满足条件的字符串给替换掉

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# g 全局标志会把遇到的所有的满足条件的字符串给替换掉
$ sed 's/1/AAA/g' example.txt
AAA0AAA,John Doe,CEO
AAA02,Jason Smith,IT Manager
AAA03,Raj Reddy,Sysadmin
AAA04,Anand Ram,Developer
AAA05,Jane Miller,Saler Manager

# 可以使用多个标志来对字符串进行替换并保存
$ sed 's/1/AAA/gipw output.txt' example.txt
10AAA,John Doe,CEO
10AAA,Jason Smith,IT Manager
10AAA,Raj Reddy,Sysadmin
10AAA,Anand Ram,Developer
10AAA,Jane Miller,Saler Manager
全局标记 w

w 将匹配结果保存到指定文件中

# w 标记会将匹配后的结果保存到指定文件中
$ sed 's/test/trial/w test.txt' data5.txt
This is a trial line.
This is a different line.
$ cat test.txt
This is a trial line.

# 把每一行碰到第一个字符串 John 替换成 lili 字符串,并写入 output.txt 中,不写数字默认就是第一个匹配到的
$ sed 's/1/AAA/1w output.txt' example.txt
$ sed 's/1/AAA/w output.txt' example.txt
$ cat output.txt
AAA01,John Doe,CEO
全局标记 p

p 只显示替换成功的行

#-n  -p 
$ sed -n 's/1/AAA/2p' example.txt
10AAA,John Doe,CEO
& 样式匹配
# 将 origin-string 替换到 replace-string 
$ sed 's/John/[&]/' example.txt
101,[John] Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#展示文件的内容
$ cat mysed.txt
Beijing
London
 
#我们使用到了&符号, 大家试着猜一猜它的作用
$ sed 's/B.*/&2008/' mysed.txt
Beijing2008
London
  • 例如:将文本的前三位数截取出来,并加上大括号,去掉后面的全部内容
$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

#1. 正则表达式的()前要加转义符\   \(\)
#2. (^[0-9]*\),.* 解释:以0-9开头的0个多多个元素 ',' 任意字符0个或多个
# sed 's@\(^[0-9]*\),.*@{\1}@g' example.txt,以数字开头,然后将后面的全部替换为空,再用标签 1 来进行 { } 的替换
$ sed 's/\(^[0-9]*\),.*/{\1}/g' example.txt
{101}
{102}
{103}
{104}
{105}

# 以逗号开头,然后将后面的全部替换为空,再用标签 1 来进行 { } 的替换
$ sed 's/\([^,]*\).*/{/1}/g'
{101}
{102}
{103}
{104}
{105}

3.5 a,i,c,y,q,r,f 脚本命令

a 追加行

格式:sed ‘[address] a the-line-to-append’ input-file

在匹配的文本之后追加

$ cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# 在第二行后面追加xxx
$ sed '2 a xxx' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
xxx
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# 在行尾追加 xxx ($表示行尾)
$ sed '$ a xxx' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager
xxx

# 在文本匹配处增加多行
$ sed '/Jason/a \aaa\bbb' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
aaa
bbb
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager
i 插入行

格式:sed ‘[address] i the-line-to-insert’ input-file

在匹配的文本前面追加

$ sed '2 i xxx' example.txt
101,John Doe,CEO
xxx
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

# 在包含“ab”的行之前插入“hello”,如果有多行,则每一行之前都会添加
$ sed -i "/ab/i hello" 1.txt
c 修改所在行

格式:sed ‘[address] c the-line-to-insert’ input-file

$ sed '/Jason/ c xxx' example.txt
101,John Doe,CEO
xxx
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager
y 字符转换

格式: sed ‘y/original-string/replace-string/’ input-file

与s区别:只转换相同字符数的字符串

$ cat a.txt
abcdef
1234

$ sed 'y/abcde/ABCDE/' a.txt
ABCDEF
1234
q 终止执行

示例:sed ‘3 q’ input-file 执行完第3行后终止

sed ‘/Anand/ q’ input-file匹配到 Anand 行后退出

cat example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
104,Anand Ram,Developer
105,Jane Miller,Saler Manager

$ sed '3 q' example.txt
101,John Doe,CEO
102,Jason Smith,IT Manager
103,Raj Reddy,Sysadmin
r 插入文件中的文本

r 命令用于将一个独立文件的数据插入到当前数据流的指定位置,该命令的基本格式为:

[address]r filename

$ cat data12.txt
This is an added line.
This is the second added line.

# 将文件中的文本插入指定文件后
$ sed '3r data12.txt' data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is an added line.
This is the second added line.
This is line number 4.

# 如果你想将指定文件中的数据插入到数据流的末尾,可以使用 $ 地址符,例如:
$ sed '$r data12.txt' data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.
This is an added line.
This is the second added line.
f 执行外部文件中的命令

如果你的 sed 命令的 command 部分很长,那么可以将内容写到一个单独的文件中,然后使用-f选项来指定这个文件作为我们 sed 命令的 command 部分:

$ cat test.txt
<html>
<title>First Wed</title>
<body>
h1Helloh1
h2Helloh2
h3Helloh3
</body>
</html>

#使用正则表示式给所有第一次匹配的h1、h2、h3添加<>,给第二次匹配的h1、h2、h3添加</>
$ cat sed.sh
/h[0-9]/{
    s//\<&\>/1
    s//\<\/&\>/2
}
d 删除脚本命令

如果需要删除文本中的特定行,可以用 d 脚本命令,它会删除指定行中的所有内容。但使用该命令时要特别小心,如果你忘记指定具体行的话,文件中的所有内容都会被删除,举个例子:

$ cat data1.txt
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
The quick brown fox jumps over the lazy dog
$ sed 'd' data1.txt
# 什么也不输出,证明成了空文件


# 当和指定地址一起使用时,删除命令显然能发挥出大的功用。可以从数据流中删除特定的文本行。
$ cat data6.txt
This is line number 1.
This is line number 2.
This is line number 3.
This is line number 4.

# 通过行号指定,比如删除 data6.txt 文件内容中的第 3 行:
$ sed '3d' data6.txt
This is line number 1.
This is line number 2.
This is line number 4.

# 删除 data6.txt 文件内容中的第 2、3行
$ sed '2,3d' data6.txt
This is line number 1.
This is line number 4

#删除第 1~3 行的文本数据
$ sed '/1/,/3/d' data6.txt
This is line number 4.

# 删除第 3 行开始的所有的内容
$ sed '3,$d' data6.txt
This is line number 1.
This is line number 2.

# 删除1~2之外的所有行
$ sed ‘1,2!d’ 1.txt

# 删除奇数行
$ sed '1~2d' 1.txt

3.5 常用操作

sed 删除文本中的空白行
  • 删除文本中所有空白行

    $ sed '/^$/d' a.txt
    
  • 删除连续的空白行

    $ sed '/./,/^$/!d' a.txt
    
  • 删除文本开头的空白行

    $ sed '/./,$!d' a.txt
    
  • 删除结尾的空白行

    $ sed '{
    > :start
    > /^\n*$/{$d; N; b start}
    > }' a.txt
    
行首添加#
#1,3行首添加#
sed '1,3 s/^/#/g' a.txt
#12345
#23456
#34567
45678

4.awk【擅长取列】

​ awk 命令也是逐行扫描文件(从第 1 行到最后一行),寻找含有目标文本的行,如果匹配成功,则会在该行上执行用户想要的操作;反之,则不对行做任何处理。

简介: 常用来做列数据切分与提取(说人话就是把指定行按指定格式分割,默认分隔符是空格)

4.1 awk语法

awk [选项] '脚本命令' 文件名

awk [选项] '匹配规则{执行命令}' 文件名

4.2 awk选项

选项含义
-F fs指定输入行的分隔符,awk 命令默认分隔符为空格或制表符。
-f file从脚本文件中读取 awk 脚本指令,以取代直接在命令行中输入指令。
-v var=val在执行处理过程之前,设置一个变量 var,并给其设备初始值为 val。

注意:

​ 1. ’匹配规则‘:表示从哪个地方开始执行,如:1,3 表示第1行到第 3 行;或者写触发事件:BEGIN、END

​ 2. 整个‘脚本命令’是用单引号’ '括起,而其中的 ‘执行命令’ 部分需要用大括号{}

​ 3. 如果没有指定 ’执行命令‘,则默认会把匹配的行输出;如果不指定’匹配规则‘,则默认匹配文本中所有的行

举例:test.txt有N个空白行,就会输出N个Blank line。

$ awk '/^$/ {print "Blank line"}' test.txt  

以:分割,筛选以/root开头,显示结果每行的第一个字段和第七个阻断

$ awk -F ":" '/^root/{print $1,$7}' test.txt

awk从文件中读取命令

$ cat awk.sh
{print $1 "'s home directory is " $6}

# 按 :分割,分割后执行 awk.sh 中的命令
$ awk -F: -f awk.sh /etc/passwd
root's home directory is /root
bin's home directory is /bin
daemon's home directory is /sbin
adm's home directory is /var/adm
lp's home directory is /var/spool/lpd
...
Christine's home directory is /home/Christine
Samantha's home directory is /home/Samantha
Timothy's home directory is /home/Timothy

4.3 awk字段变量

awk 的主要特性之一是其处理文本文件中数据的能力,它会自动给一行中的每个数据元素分配一个变量。

默认情况下,awk 会将如下变量分配给它在文本行中发现的数据字段:

  • $0 代表整个文本行;
  • $1 代表文本行中的第 1 个数据字段;
  • $2 代表文本行中的第 2 个数据字段;
  • $n 代表文本行中的第 n 个数据字段。
# awk 程序读取文本文件,只显示第 1 个数据字段的值:
$ cat data2.txt
One line of test text.
Two lines of test text.
Three lines of test text.

# 在 awk 中,默认的字段分隔符是任意的空白字符
$ awk '{print $1}' data2.txt
One
Two
Three

# 可以用 -F 选项手动指定分隔符 例如:
$ awk -F'#''{print $1}' data2.txt

4.4 awk使用多个命令

awk 允许将多条命令组合成一个正常的程序。只要在命令之间放个;分号即可,例如:

$ echo "My name is Rich" | awk '{$4="Christine"; print $0}'
My name is Christine

# 也可以分开写

$ awk '{
> $4="Christine"
> print $0}'
My name is Christine

注意,此例中因为没有在命令行中指定文件名,awk 程序需要用户输入获得数据,因此当运行这个程序的时候,它会一直等着用户输入文本,此时如果要退出程序,只需按下 Ctrl+D 组合键即可。

4.5 BEGIN关键字

awk 中还可以指定脚本命令的运行时机。默认情况下,awk 会从输入中读取一行文本,然后针对该行的数据执行程序脚本,但有时可能需要在处理数据前运行一些脚本命令,这就需要使用 BEGIN 关键字。

BEGIN 会强制 awk 在读取数据前执行该关键字后指定的脚本命令,例如:

$ cat data3.txt
Line 1
Line 2
Line 3
$ awk 'BEGIN {print "The data3 File Contents:"}
\> {print $1}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3

可以看到,这里的脚本命令中分为 2 部分,BEGIN 部分的脚本指令会在 awk 命令处理数据前运行,而真正用来处理数据的是第二段脚本命令。

4.6 END关键字

和 BEGIN 关键字相对应,END 关键字允许我们指定一些脚本命令,awk 会在读完数据后执行它们,例如:

$ awk 'BEGIN {print "The data3 File Contents:"}
\> {print $1}
\> END {print "End of File"}' data3.txt
The data3 File Contents:
Line 1
Line 2
Line 3
End of File

4.7 awk内置变量

awk有许多内置变量用来设置环境信息,这些变量可以被改变,下面给出了最常用的一些变量。

  • ARGC 命令行参数个数

  • ARGV 命令行参数排列

  • ENVIRON 支持队列中系统环境变量的使用

  • FILENAME awk浏览的文件名

  • FNR 浏览文件的记录数

  • FS 设置输入域分隔符,等价于命令行 -F选项

  • NF 浏览记录的域的个数(切割)

  • NR 已读的记录数

  • OFS 输出域分隔符

  • ORS 输出记录分隔符

  • RS 控制记录分隔符

实例:

统计/etc/passwd:文件名,每行的行号,每行的列数,对应的完整行内容:

$ awk -F ':' '{print"filename:" FILENAME ",NR:" NR", NF:" NF ",linecontent:"$0}' /etc/passwd
filename:/etc/passwd,NR:1,NF:7,linecontent:root:x:0:0:root:/root:/bin/bash
filename:/etc/passwd,NR:2,NF:7,linecontent:daemon:x:1:1:daemon:/usr/sbin:/bin/sh
filename:/etc/passwd,NR:3,NF:7,linecontent:bin:x:2:2:bin:/bin:/bin/sh
filename:/etc/passwd,NR:4,NF:7,linecontent:sys:x:3:3:sys:/dev:/bin/sh

使用printf替代print,可以让代码更加简洁,易读

$ awk  -F ':' '{printf("filename:%s,linenumber:%s,columns:%s,linecontent:%s\n",FILENAME,NR,NF,$0)}'/etc/passwd

注意:命令结尾的路径是绝对路径

关系运算模式:awk -F ‘#’ ‘NF==5 {print $1}’ test

# 打印以'#'分隔后,数量=5的 第一段字符
$ awk -F '#' 'NF==5 {print $1}' test

# 看命令自己翻译
$ awk -F '#' 'NF>=4 && NF<=5 {print $1}' test

4.8 awk变量和赋值

除了awk的内置变量,awk还可以自定义变量。

下面统计/etc/passwd的账户人数

$ awk '{count++;print $0;} END{print "user count is ",count}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
......
user count is  40

count是自定义变量。之前的action{}里都是只有一个print,其实print只是一个语句,而action{}可以有多个语句,以;号隔开。

这里没有初始化count,虽然默认是0,但是妥当的做法还是初始化为0:

$ awk 'BEGIN {count=0;print "[start]user count is ",count} {count=count+1;print $0;} END{print "[end]user count is ",count}' /etc/passwd

[start]user count is  0
root:x:0:0:root:/root:/bin/bash
...
[end]user count is  40

统计某个文件夹下的文件占用的字节数

$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print"[end]size is ", size}'
[end]size is  8657198

#如果以M为单位显示:
$ ls -l |awk 'BEGIN {size=0;} {size=size+$5;} END{print"[end]size is ", size/1024/1024,"M"}'
[end]size is  8.25889 M

注意:ls -l,会罗列出所有文件的信息,默认以空格分个,$5正好是字节大小。统计不包括文件夹的子目录

5.regex【正则表达式】

正则就是用有限的符号,表达无限的序列

5.1 匹配字符

  • . 匹配任意单个字符,不能匹配空行
  • [] 匹配指定范围内的任意单个字符,[0-9a-zA-Z]、[a-zA-Z]、 [A-Z]、[a-z]
  • ^[0-9] 以0-9开头
  • [0-9]$ 以0-9结尾
  • [^] 取反

5.2 配置次数

  • ***** 匹配前面的字符任意次,包括0次,贪婪模式:尽可能长的匹配
  • .* 任意长度的任意字符,不包括0次
  • ? 匹配其前面的字符0 或 1次
  • \+ 匹配其前面的字符至少1次
  • {n} 匹配前面的字符n次
  • {m,n} 匹配前面的字符至少m 次,至多n次
  • {,n} 匹配前面的字符至多n次
  • {n,} 匹配前面的字符至少n次

注意:{}在正则表达式中需要转意,而{}()不需要。

5.3 出现位置

  • ^ 行首锚定,用于模式的最左侧
  • $ 行尾锚定,用于模式的最右侧
  • ^PATTERN$,用于模式匹配整行
  • ^$ 空行
  • ^[[:space:]].*$ 空白行
  • < 或 \b 词首锚定,用于单词模式的左侧
  • > 或 \b 词尾锚定;用于单词模式的右侧

5.4 转意字符

\是转移字符,其后面的字符会代表不同的意思,常用的转意字符:

转移字符含义
\n匹配换行符
\r匹配回车符
\t匹配制表符
\w匹配任意一个数字、字母、下划线
\W匹配非数字、字母、下划线的任意一个字符(特殊字符)
\d匹配数子字符0~9
\D匹配非数字字符 !0~9
\\匹配\

5.5 选择表达式

正则中用|来表示分组,a|b表示匹配a或者b的意思

123|456|789 // 匹配 123 或 456 或 789

5.6 分组与引用

引用的语法是 \数字,数字代表引用前面第几个捕获分组(括号中的匹配),注意非捕获分组不能被引用

\ 表示转意字符

<([a-z]+)><\/\1> // 可以匹配 `<span></span>``<div></div>`

5.7 实例

$ cat c.txt 
abc
abcc
abccc
abcccc
aaa
ac
yyycc

# \? 匹配其前面的字符0或1次(匹配的是ABC出现的次数)
$ grep "abc\?" c.txt
abc
abcc
abccc
abcccc
abccccc

# \+ 匹配其前面的字符至少1次(匹配的是ABC出现的次数)
$ grep "abc\+" c.txt
abc
abcc
abccc
abcccc
abccccc

$ grep "c\+" c.txt 
abc
abcc
abccc
abcccc
abccccc
ac
yyycc

#前面字符至少出现过3次
$ grep "c\{3,\}" c.txt
abccc
abcccc
abccccc

#以a开头
$ grep "^a" c.txt
abc
abcc
abccc
abcccc
abccccc
aaa
ac

#以c结尾
$ grep "c$" c.txt
abc
abcc
abccc
abcccc
abccccc
ac
yyycc

#匹配y开头,c结尾的字符  \是转意字符
$ grep "\<y.*c\>" c.txt
yyycc

6.wc【统计】

Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数、字数、行数,并将统计结果显示输出

#1.命令格式:
wc [选项]文件...
#2.命令功能:
统计指定文件中的字节数、字数、行数,并将统计结果显示输出。该命令统计指定文件中的字节数、字数、行数。如果没有给出文件名,则从标准输入读取。
wc同时也给出所指定文件的总统计数。
#3.命令参数:
-c 统计字节数。
-l 统计行数。
-m 统计字符数。这个标志不能与 -c 标志一起使用。
-w 统计字数。一个字被定义为由空白、跳格或换行字符分隔的字符串。
-L 打印最长行的长度。
-help 显示帮助信息
--version 显示版本信息

#cat查看文件,查找关键字(grep),统计(wc -l)
语法:cat 文件 | grep 关键字 | wc -l
cat /proc/meminfo |grep Swap | wc -l

linux常用查看日志命令总结

1. tail动态实时查看日志

tail命令是最常用的查看日志语句,以日志文件server.log为例

tail -f filename

# 实时展示日志末尾内容,默认最后10行,相当于增加参数 -n 10
$ tail -f server.log

# 查看日志最后20行内容并实时更新日志
$ tail -f -n 20 server.log

# 查看日志正数20行内容
$ tail -n +20 server.log

# 查看日志最后20行内容并实时更新日志
$ tail -f -n 20 server.log

# 查看日志正数20行内容
$ tail -n +20 server.log

退出tail命令 Ctrl+c

2. tail配合grep关键字查询

在快速更新的大量日志中查询关键列非常不方便,这是就需要

$ tail -f log_file | grep ‘error’

-C 选项来显示检索结果的前后几行,-A 选项展示检索结果后几行,-B选项展示检索结果前几行

$ tail -f log_file | grep -C 5 ‘xx关键字’

3. cat关键字搜索

cat 区别于tail是对日志进行全文搜索,其中-n的作用是显示行号

$ cat -n filename |grep “xx关键字”

-C 选项来显示检索结果的前后几行,-A 选项展示检索结果后几行,-B选项展示检索结果前几行

$ cat -n log_file | grep -C 5 ‘http-nio-8091-exec-7’
  • 4
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值