LInux-文本处理相关命令笔记

目录

  • 文本处理相关命令
    • 正则表达式
      • 介绍
        • BRE和ERE
    • seq
    • xargs
      • 常用选项
      • 常用使用方法
    • uniq
      • 介绍
      • 常见选项
      • 常见使用方法
      • 实例
    • tr
      • 常用选项
      • 常见使用方法
      • 能转换的原因
    • grep
      • 常见选项
          • grep -v 选项
        • -v和`[^..]`的区别
      • 常见使用方法
        • 使用
      • 总结
    • cut
      • 介绍
      • 使用
    • sort
      • 介绍
        • 语法
        • 参数
      • 使用
        • 去重
      • 排序原则
        • 按字典序排序
        • 按数值排序
        • 按月份排序
        • 按照时间戳排序
        • k选项更深的用法
      • 练习
          • 1.过滤出/etc/passwd中用户名sc的用户,按照基本组id倒序排序输出
          • 2.统计出/var/log下,文件大小前五的以.log结尾的文件
        • 3.统计出当前网络连接总共有那些状态,每个状态有多少个?
        • 4.统计scwebsite2_ssl.log日志文件中,访问量前10的ip
        • 5.系统监控的脚本
    • cat
      • 介绍
      • 基本使用
      • 基本用法
        • 将多个文件合并输出
        • 显示行号
        • 将特定行输出
        • 显示特殊字符
      • 总结
        • 实例
    • split
      • 语法
      • 常用选项
      • `-C`和`-b`的区别
      • 常见用法
    • awk
      • 介绍
        • 语法
          • **注意事项**
        • 选项
        • 基本用法
      • 运算符
        • 注意事项
      • 内建变量
        • 使用
      • 内置函数
        • split
        • substr
        • 使用
      • awk中的if和for
      • awk中的数组
    • paste
      • 语法
      • 选项
        • 示例
    • join
      • 命令语法
      • 命令选项
      • 常见用法
        • 连接两个文件的行
        • 指定连接的字段
        • 打印没有匹配到的行
        • 指定空白字段值
        • 忽略大小写进行匹配
        • 指定字段分隔符
        • 处理大文件
        • 根据单个字段进行连接
        • 根据多个字段进行连接
        • 根据字段名进行连接
      • 注意事项
      • 总结
    • sed
      • 介绍
        • 选项
        • 动作
        • 正则
        • 模式空间:
      • 用法:
        • sed中标签的用法
        • a和i的用法
        • 难一点的运用
        • 注意事项:
          • sed单引号和双引号的区别:

LInux-文本处理相关命令笔记_第1张图片

文本处理相关命令

正则表达式

介绍

在Shell中,正则表达式是一种字符串模式匹配工具,用于在文本中查找和处理特定的字符串。Shell中支持两种类型的正则表达式:基本正则表达式(Basic Regular Expressions,BRE)和扩展正则表达式(Extended Regular Expressions,ERE)。

正则表达式通常包含普通字符和特殊字符两种类型。普通字符是指除了特殊字符以外的字符,特殊字符则是一些特殊含义的字符,用于表示一些特定的字符集或字符序列。以下是一些常见的正则表达式特殊字符。

BRE和ERE

在Shell中,有两种常用的正则表达式:基本正则表达式和扩展正则表达式。它们的区别在于支持的元字符和特殊语法的不同。下面分别介绍它们的特点和用法。

基本正则表达式

基本正则表达式(BRE)是最早的正则表达式语法,支持的元字符比较少,但功能足够强大。在BRE中,一些特殊字符必须进行转义才能作为元字符使用,如*+?等。

以下是一些BRE中常用的元字符和特殊语法:

  • .:匹配任意单个字符
  • []:匹配一个字符集中的任意一个字符
  • [^]:匹配一个不在字符集中的字符
  • \:转义字符
  • ^:匹配行首,代表以什么开头
  • $:匹配行尾,代表以什么结尾的行
  • ():分组
  • *:匹配前一个字符的零个或多个
  • \{n\}:匹配前一个字符的n个
  • \{n,\}:匹配前一个字符的至少n个
  • \{n,m\}:匹配前一个字符的n到m个

例如,BRE表达式^[a-zA-Z]*$将匹配只包含字母的行。^$代表空行,.*代表所有的字符(任意字符)

在Shell中,使用grep命令可以使用BRE。默认情况下,grep使用的就是BRE。

扩展正则表达式

扩展正则表达式(ERE)是BRE的扩展,支持的元字符更多,也更易用。在ERE中,特殊字符不需要转义即可作为元字符使用。

以下是一些ERE中常用的元字符和特殊语法:

  • .:匹配任意单个字符
  • []:匹配一个字符集中的任意一个字符
  • [^]:匹配一个不在字符集中的字符
  • ():分组
  • |:或
  • *:匹配前一个字符的零个或多个
  • +:匹配前一个字符的一个或多个
  • ?:匹配前一个字符的零个或一个
  • {n}:匹配前一个字符的n个
  • {n,}:匹配前一个字符的至少n个
  • {n,m}:匹配前一个字符的n到m个
  • \<(\b):表示词首部以什么开头
  • \>(\b):表示词尾部以什么结束
  • \\表示abc这个单词

例如,ERE表达式^[a-zA-Z]*$和BRE表达式是等价的。

在Shell中,可以使用grep命令的-E选项来启用ERE模式。例如,grep -E '^[a-zA-Z]*$' file.txt将使用ERE模式匹配file.txt中只包含字母的行。

除了grep命令之外,还有一些其他的Shell命令,如sed和awk也支持ERE。

seq

在Linux/Unix shell中,seq是一个用于生成数字序列的命令。它可以按照指定的步长生成一系列数字,可以用于循环、迭代等操作。

seq命令的基本语法格式如下:

seq [OPTION]... LAST
seq [OPTION]... FIRST LAST
seq [OPTION]... FIRST INCREMENT LAST

其中,LAST表示序列中的最后一个数字,FIRST表示序列中的第一个数字,INCREMENT表示序列中相邻数字之间的步长。下面是一些常用的选项参数:

  • -w, --equal-width:输出宽度相等的数字序列。
  • -s, --separator=STRING:指定序列中相邻数字之间的分隔符。
  • -f, --format=FORMAT:指定输出格式,其中FORMAT为printf样式的格式字符串。例如,-f %03g表示输出三位数的格式。

下面是一些seq命令的示例:

  1. 输出1到10的数字序列:
seq 10

输出结果:

1
2
3
4
5
6
7
8
9
10
  1. 输出从2到10的数字序列:
seq 2 10

输出结果:

2
3
4
5
6
7
8
9
10
  1. 输出从1到10,步长为2的数字序列:
seq 1 2 10

输出结果:

1
3
5
7
9
  1. 输出宽度相等的数字序列,每个数字占用3个字符的宽度:
seq  -f "%03g" 1 10

输出结果:

001
002
003
004
005
006
007
008
009
010
  1. 输出从1到10的数字序列,并在相邻数字之间使用逗号作为分隔符:
seq -s, 1 10

输出结果:

1,2,3,4,5,6,7,8,9,10

需要注意的是,seq命令只能生成整数序列,不能生成浮点数序列。如果需要生成浮点数序列,可以使用其他的工具或编程语言来实现。

以上就是seq命令的简单介绍和一些常用的选项参数和示例。

xargs

xargs 是一个 Unix/Linux 系统中的实用程序,它的作用是将标准输入转化为命令行参数。通过使用 xargs,我们可以将一些命令的输出或者管道的内容作为参数传递给另外一个命令进行处理。这个命令非常有用,特别是当你需要在大量的文件或者目录中搜索或者执行一些操作时。

下面是 xargs 的一些常用选项和使用方法:

常用选项

  • -n:指定每次传递给命令的参数个数。
  • -I:指定替换字符串。用字符串 {} 表示将被替换的参数。
  • -d:指定分隔符。默认情况下,分隔符是空格,但是可以通过 -d 选项指定其他分隔符。
  • -P:指定并行处理的任务数。
  • -t:打印出执行的命令本身。

常用使用方法

  • find 命令的输出作为参数传递给 rm 命令来删除文件:

    find . -type f -name "*.txt" -print0 | xargs -0 rm
    

    这里使用了 -print0 选项来保证 find 命令输出的文件名包含空格或者其他特殊字符时不会被错误地分割,同时使用了 -0 选项来告诉 xargs 使用 \0 作为分隔符。

  • grep 命令的输出作为参数传递给 wc 命令来计算文件中包含指定字符串的行数:

    cat file.txt | grep "hello" | xargs -I {} wc -l {}
    

    这里使用了 -I 选项来将 {} 替换为 grep 命令输出的每一行,然后将其作为参数传递给 wc 命令。

  • 在并行处理的情况下,将 find 命令的输出作为参数传递给 gzip 命令来压缩文件:

    find . -type f -name "*.txt" -print0 | xargs -0 -P 4 -n 1 gzip
    

    这里使用了 -P 选项来指定 4 个并行任务,使用了 -n 1 选项来保证每个任务只处理一个文件。

  • 将数字从行变为列

    [root@localhost 5-6]# seq 5|xargs 
    1 2 3 4 5
    

uniq

介绍

在 Shell 中,uniq 命令可以用于从一个文本文件或者标准输入中删除重复的行,并且可以计算重复行的数量。下面是一些 uniq 命令的常见选项和使用方法:

常见选项

  • -c:显示每行出现的次数,并在行首加上计数值;
  • -d:仅显示重复的行;
  • -u:仅显示不重复的行;
  • -f n:从第 n 个字段开始比较(默认从第一个字符开始比较);
  • -s n:跳过前 n 个字符后再进行比较;
  • -i:忽略大小写。

常见使用方法

  • 删除文件中的重复行:

    uniq file.txt > newfile.txt
    

    这条命令将 file.txt 中的重复行删除,并将结果输出到 newfile.txt 中。

  • 统计每个重复行出现的次数:

    sort file.txt | uniq -c
    

    这条命令将 file.txt 中的所有行按字典序排序后,统计重复行出现的次数,并在行首加上计数值。

  • 仅显示重复的行:

    sort file.txt | uniq -d
    

    这条命令将 file.txt 中的所有行按字典序排序后,仅显示重复的行。

  • 仅显示不重复的行:

    sort file.txt | uniq -u
    

    这条命令将 file.txt 中的所有行按字典序排序后,仅显示不重复的行。

  • 从第 n 个字段开始比较:

    cat file.txt | cut -d ' ' -f 2- | sort | uniq
    

    这条命令将 file.txt 中每一行的第一个字段删除后,按字典序排序,并仅保留不重复的行。

  • 忽略大小写:

    sort file.txt | uniq -i
    

    这条命令将 file.txt 中的所有行按字典序排序后,忽略大小写,并仅保留不重复的行。

实例

效果是去重,只会把挨着的去重

uniq -c :去重并且统计数量

[root@localhost shell-test]# awk -F" " ‘{print $2}’ grade.txt |sort|uniq -c
2 chinese
3 english
4 math

tr

在 Shell 中,tr 命令用于转换或删除字符。tr 命令的基本语法如下:

tr [OPTION] SET1 [SET2]

其中,OPTION 表示命令选项,SET1 表示源字符集合,SET2 表示目标字符集合。tr 命令将 SET1 中的字符转换为 SET2 中对应的字符,或者删除 SET1 中的字符。

下面是一些常见的 tr 命令的选项和用法:

常用选项

  • -c:将 SET1 中未包含的字符保留,并将其它字符删除;
  • -d:删除 SET1 中的字符;
  • -s:将 SET1 中连续出现的字符压缩为单个字符;
  • -t:指定字符集合 SET2 的长度与 SET1 相同。

常见使用方法

  • 将文件中的所有大写字母转换为小写字母:

    cat file.txt | tr 'A-Z' 'a-z'
    

    这条命令将 file.txt 中的所有大写字母转换为小写字母,并将结果输出到标准输出中。

  • 删除文件中的所有空格:

    cat file.txt | tr -d ' '
    

    这条命令将 file.txt 中的所有空格删除,并将结果输出到标准输出中。

  • 将文件中的所有制表符转换为空格:

    cat file.txt | tr '\t' ' '
    

    这条命令将 file.txt 中的所有制表符转换为空格,并将结果输出到标准输出中。

  • 将文件中的连续空行压缩为单个空行:

    cat file.txt | tr -s '\n'
    

    这条命令将 file.txt 中的连续空行压缩为单个空行,并将结果输出到标准输出中。

  • 保留文件中的所有字母和数字,删除其它字符:

    cat file.txt | tr -c '[:alnum:]' '\n'
    

    这条命令将 file.txt 中的所有非字母和数字字符删除,并将结果输出到标准输出中。

  • 将数字转变为对应的英文

[root@localhost 5-6]# echo 1232123|tr 123 abc
abcbabc

能转换的原因

tr 命令可以进行字符转换的原因在于,它利用了 ASCII 码表或 Unicode 码表中每个字符对应的整数值。在计算机中,每个字符都有一个对应的整数值,这个整数值称为字符的编码值。不同的字符集使用不同的编码方式,比如 ASCII 码表使用 7 位二进制数表示字符,而 Unicode 码表使用 16 位或更多位二进制数表示字符。

tr 命令中的 SET1SET2 表示源字符集和目标字符集,可以使用字符或字符范围的方式指定集合中的字符。tr 命令在转换时,会将 SET1 中的字符与 SET2 中对应的字符一一映射,从而进行字符转换。因此,只有当源字符集和目标字符集中的字符对应的编码值是一一对应的时,tr 命令才能进行正确的字符转换。

例如,将大写字母转换为小写字母,是因为 ASCII 码表中大写字母和小写字母的编码值相差恰好为 32。因此,可以将大写字母的编码值加上 32,即可得到相应的小写字母的编码值。

总之,tr 命令能够进行字符转换,是因为它基于字符的编码值进行转换。

grep

在 Shell 中,grep 命令是一种用于在文件中查找指定字符串的强大工具。grep 命令的基本语法如下:

grep [OPTIONS] PATTERN [FILE...]

其中,OPTIONS 表示命令选项,PATTERN 表示要查找的字符串模式,FILE 表示要查找的文件名。如果没有指定文件名,则 grep 命令将从标准输入中读取数据。

下面是一些常见的 grep 命令的选项和用法:

常见选项

  • -i:忽略大小写
  • -v:反向匹配,只输出不匹配的行
  • -w:只匹配整个单词,而不是单词的一部分
  • -n:在每行输出匹配的行号
  • -c:仅输出匹配的行数
  • -l:只输出包含匹配项的文件名
  • -r:递归搜索指定目录下的所有文件
  • -E:使用扩展正则表达式语法
  • -F:将模式视为固定字符串而不是正则表达式
  • -o 是一个非常有用的命令选项,用于在匹配文本中仅输出匹配的部分,而不是整个行或文件。
  • -A 表示显示匹配行的后 num 行文本
  • -B 表示显示匹配行的前 num 行文本
  • -C 表示显示匹配行前后 num 行文本
grep -v 选项

-v 选项是 grep 命令的一个选项,用于查找不包含指定模式的文本行。例如,如果我们要从文件 file.txt 中查找不包含字符串 “error” 的文本行,我们可以运行以下命令:

grep -v "[0-9]" file.txt
-------------------------------------
[root@localhost 5-8]# grep -v "[0-9]" file.txt
dasdas

此命令将返回不包含字符串 "[0-9]"的所有文本行。

[^0-9] 正则表达式

[^0-9] 是一个正则表达式模式,它用于匹配不包含数字的文本。在这个模式中,^ 符号表示 “非”。因此,[^0-9] 表示匹配不是数字的字符。例如,如果我们要从文件 file.txt 中查找不包含数字的文本行,我们可以运行以下命令:

grep -E '^[^0-9]+$' file.txt
-------------------------------------------
[root@localhost 5-8]# grep  "[^0-9]" file.txt
dasdas  12321
dasdas

此命令将使用 -E 选项来启用扩展正则表达式,从而匹配所有不包含数字的行。

可以在此基础上接-o,可以输出仅配备的行

[root@localhost 5-8]# grep  -o "[^0-9]" file.txt
-------------------------------------------------------------
dasdas

dasdas

-v和[^..]的区别

grep 命令中,-v 选项和 [^0-9] 正则表达式都用于搜索与给定模式不匹配的文本行。下面是这两种方法的详细介绍和使用示例。

定义file.txt文件,数据如下:

[root@localhost 5-8]# cat file.txt 
dasdas  12321
2131
  • -v 选项用于查找不包含给定模式的文本行,而 [^0-9] 正则表达式用于查找不包含数字的文本行
  • -v 选项是 grep 命令的一个选项,而 [^0-9] 是一个正则表达式模式。
  • -v 选项可以与其他选项一起使用,例如 -i-w-r,而 [^0-9] 只能在正则表达式中使用。

总之,-v 选项用于查找不包含给定模式的文本行,而 [^0-9] 正则表达式用于查找不包含数字的文本行。它们可以在不同的情况下使用,具体取决于您的需求和搜索条件。

常见使用方法

  • 查找文件中包含指定字符串的行:

    grep 'pattern' file.txt
    

    这条命令将在 file.txt 文件中查找包含 “pattern” 字符串的行,并将结果输出到标准输出中。

  • 查找多个文件中包含指定字符串的行:

    grep 'pattern' file1.txt file2.txt file3.txt
    

    这条命令将在 file1.txt、file2.txt 和 file3.txt 文件中查找包含 “pattern” 字符串的行,并将结果输出到标准输出中。

  • 查找目录中所有文件中包含指定字符串的行:

    grep -r 'pattern' /path/to/directory
    

    这条命令将递归地查找 /path/to/directory 目录及其子目录中所有文件中包含 “pattern” 字符串的行,并将结果输出到标准输出中。

  • 忽略大小写,查找文件中包含指定字符串的行:

    grep -i 'pattern' file.txt
    

    这条命令将在 file.txt 文件中查找包含 “pattern” 字符串(忽略大小写)的行,并将结果输出到标准输出中。

  • 反转查找结果,查找文件中不包含指定字符串的行:

    grep -v 'pattern' file.txt
    

    这条命令将在 file.txt 文件中查找不包含 “pattern” 字符串的行,并将结果输出到标准输出中。

  • 只输出匹配模式的行数:

    grep -c 'pattern' file.txt
    

    这条命令将在 file.txt 文件中查找包含 “pattern” 字符串的行数,并将结果输出到标准输出中。

  • 显示匹配行前后的文本

    假设我们有一个名为 file.txt 的文本文件,其中包含一些文本行。我们可以使用 grep 命令来查找文件中包含字符串 pattern 的行,并在每个匹配行的前后显示 2 行文本,例如:

    grep -C 2 'pattern' file.txt
    
  • 仅显示匹配行后的文本

    假设我们有一个名为 numbers.txt 的文本文件,其中包含一些数字。我们可以使用 grep 命令来查找文件中包含数字 123 的行,并在每个匹配行后显示 3 行文本,例如:

    grep -A 3 '123' numbers.txt
    
  • 仅显示匹配行前的文本

    假设我们有一个名为 urls.txt 的文本文件,其中包含一些 URL。我们可以使用 grep 命令来查找文件中包含字符串 http 的行,并在每个匹配行前显示 1 行文本,例如:

    grep -B 1 'http' urls.txt
    

    注意事项

    • 为了避免与正则表达式中的特殊字符冲突,必须将模式括在引号中。
    • 如果上下文行的数量太多,输出可能会变得很混

使用

下面是一些常见的正则表达式用法及示例:

  • 匹配以 xiao 开头的单词

    [root@localhost ~]# echo "xiaohua lihua yangyang"|egrep "\bxiao" -o
    

    [root@localhost ~]# echo "xiaohua lihua yangyang"|egrep "\
  • 匹配以 hua 结尾的行

    [root@localhost ~]# echo "xiaohua lihua yangyang"|egrep "hua\>" -o
    

    [root@localhost ~]# echo "xiaohua lihua yangyang"|egrep "hua\b" -o
    
  • 匹配以 hello 开头的行:

    grep '^hello' file.txt
    
  • 匹配以 world 结尾的行:

    grep 'world$' file.txt
    
  • 匹配包含 hello 的行:

    grep 'hello' file.txt
    
  • 匹配包含 helloworld 的行:

    grep 'hello\|world' file.txt
    
  • 匹配以字母 a 开头,后跟任意字符,再后跟字母 z 结尾的行:

    grep '^a.*z$' file.txt
    
  • 匹配以字母 a 开头,后跟一个或多个字母 b,再后跟字母 c 结尾的行:

    grep '^a\+b\+c$' file.txt
    
  • 匹配包含字符串 abc 的行:

    grep 'abc' file.txt
    
  • 匹配以大写字母开头的单词:

    grep '\b[A-Z]\w*' file.txt
    
  • 匹配数字

要匹配一个或多个数字,可以使用\d+(ERE)或[0-9]\+(BRE)。

例如,在文件中查找包含一个或多个数字的行,可以使用下面的命令:

grep -E '\d+' file.txt    # ERE 模式
grep '[0-9]\+' file.txt  # BRE 模式
  • 匹配IP地址

要匹配IPv4地址,可以使用\b(?:\d{1,3}\.){3}\d{1,3}\b(ERE)或\b\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\b(BRE)。

例如,在文件中查找包含IPv4地址的行,可以使用下面的命令:

grep -E '\b(?:\d{1,3}\.){3}\d{1,3}\b' file.txt   # ERE 模式
grep '\b\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}\b' file.txt  # BRE 模式
  • 匹配邮箱地址

要匹配邮箱地址,可以使用\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b(ERE)或\b[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Z|a-z]\{2,\}\b(BRE)。

例如,在文件中查找包含邮箱地址的行,可以使用下面的命令:

grep -E '\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' file.txt   # ERE 模式
grep '\b[A-Za-z0-9._%+-]\+@[A-Za-z0-9.-]\+\.[A-Z|a-z]\{2,\}\b' file.txt  # BRE 模式
  • 查找/etc/ssh/sshd_config中不含空行和以#开头的行

    [root@localhost ~]# cat /etc/ssh/sshd_config |egrep -v -n "^$|^#"
    
  • 查找/var/log/messages文件中存在字母长度范围在[14.18]的行

    [root@localhost ~]# cat /var/log/messages|egrep "\<[a-Z]{14,18}\>"
    
  • ip地址的正则表达式

    [root@localhost lianxi]# cat /var/log/secure|egrep "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])"
    

总结

正则表达式在Shell编程中是非常常用的工具,可以帮助我们快速地匹配和处理文本。本文介绍了Shell中常用的两种正则表达式语法:基本正则表达式和扩展正则表达式,分别介绍了它们的元字符和特殊语法,并给出了一些常见的用法示例。

cut

介绍

在Linux/Unix shell中,cut是一个用于剪切或截取文件中的特定字段或列的命令。它可以将文件中的每行文本按照特定的分隔符进行分割,并提取指定的字段或列。

cut命令的一般语法格式如下:

cut OPTION... [FILE]...

其中,OPTION表示cut命令的选项参数,FILE表示要处理的文件。下面是一些常用的选项参数:

  • -f:指定要提取的字段或列的位置或范围。可以通过逗号或空格分隔多个位置或范围。例如-f 1,3,5表示提取文件中的第1、3和5列。
  • -d:指定用于分隔每行文本的分隔符。默认情况下,分隔符为制表符(tab)。可以通过在选项后面指定字符来更改分隔符。例如-d :表示使用冒号作为分隔符。
  • -c:指定要提取的字符范围。可以使用-表示范围。例如-c 1-10表示提取文件中的第1到第10个字符。
  • -s:禁止输出不包含分隔符的行。

下面是一些cut命令的示例:

  1. 提取文件file.txt中的第1列:
cut -f1 file.txt
  1. 提取文件file.txt中的第1、3和5列:
cut -f1,3,5 file.txt
  1. 使用逗号作为分隔符提取文件file.txt中的第1、3和5列:
cut -d',' -f1,3,5 file.txt
  1. 提取文件file.txt中每行的前10个字符:
cut -c1-10 file.txt
  1. 提取文件file.txt中包含分隔符的行:
cut -f1 -s file.txt

需要注意的是,cut命令不会更改原始文件,而是将结果输出到标准输出流。如果需要将结果保存到文件中,可以使用重定向符号>将标准输出流重定向到一个文件中。例如:

cut -f1 file.txt > output.txt

以上就是cut命令的简单介绍和一些常用的选项参数和示例。

使用

从文本文件或者文本流中提取文本列
cut -选项 提取范围 文本文件

常见选项
-c:从指定提取范围中提取字符
-f:从指定提取范围中提取字段
-d:指定分割符,默认分隔符为tab键

提取范围
n:第n项
n-:第n项到行尾
-m:行首到第m项
n,m:第n项和第m项
n-m:第n项到第m项

tr -s " " 将连续的多个空格压缩成一个空格,因为用空格进行分割的时候,多个空格分割不了,所以需要压缩空格

[root@localhost shell-test]# w |tr -s " "|cut -d" " -f1-5
 16:45:01 up 23:15, 3
USER TTY FROM LOGIN@ IDLE
root tty1 一09 2:57m 0.05s
root pts/2 192.168.242.1 13:47 58:53
root pts/3 192.168.242.1 13:48 5.00s
[root@localhost shell-test]# echo "asdasda"|cut -c2
s
[root@localhost shell-test]# echo "asdasda"|cut -c2-6
sdasd

sort

介绍

Linux sort 命令用于将文本文件内容加以排序。

sort 可针对文本文件的内容,以行为单位来排序。

语法

sort [-bcdfimMnr][-o<输出文件>][-t<分隔字符>][+<起始栏位>-<结束栏位>][--help][--verison][文件][-k field1[,field2]]

参数

-b 忽略每行前面开始出的空格字符。
-c 检查文件是否已经按照顺序排序。
-d 排序时,处理英文字母、数字及空格字符外,忽略其他的字符。
-f 排序时,将小写字母视为大写字母。
-i 排序时,除了040至176之间的ASCII字符外,忽略其他的字符。
-m 将几个排序好的文件进行合并。
-M 将前面3个字母依照月份的缩写进行排序。
-n 依照数值的大小排序。
-u 意味着是唯一的(unique),输出的结果是去完重了的。
-o<输出文件> 将排序后的结果存入指定的文件。
-r 以相反的顺序来排序。
-t<分隔字符> 指定排序时所用的栏位分隔字符。
+<起始栏位>-<结束栏位> 以指定的栏位来排序,范围由起始栏位到结束栏位的前一栏位。
--help 显示帮助。
--version 显示版本信息。
[-k field1[,field2]] 按指定的列进行排序。

使用

[root@localhost shell-test]# cat grade.txt|sort
hua   c 90
li    c 82
yu    y 80
zhang y 70
[root@localhost shell-test]# cat grade.txt|sort -r
##接 -r 倒序
zhang y 70
yu    y 80
li    c 82
hua   c 90

对分数进行排列,如果后面没有接**-n**就是按照字符串排序了,而且只是按照字符串的第一个字符

[root@localhost shell-test]# cat grade.txt|sort -k3
zhang y 70
yu    y 80
li    c 82
hua   c 90

这是按照数组进行排序

[root@localhost shell-test]# cat grade.txt|sort -k3 -n -r
hua   c 90
li    c 82
yu    y 80
zhang y 70

去重

排序和去重一般配合使用

[root@localhost shell-test]# awk -F" " '{print $2}' grade.txt |sort -u 
## sort -u 有去重效果
chinese
english
math

[root@localhost shell-test]# awk -F" " '{print $2}' grade.txt |sort|uniq -c
      2 chinese
      3 english
      4 math

排序原则

在 Shell 环境下,sort 是一个非常常用的命令,用于对文本文件进行排序。sort 命令可以按照指定的规则对文本进行排序,以下是 sort 命令的一些常见排序规则:

按字典序排序

按照 ASCII 码表中的顺序对文本进行排序,默认情况下,sort 命令会按照每行第一个字符开始进行排序。可以使用 -r 选项进行倒序排序。

例如,要按照字典序对文件 file.txt 进行排序,可以使用以下命令:

sort file.txt

按数值排序

按照数值大小对文本进行排序,可以使用 -n 选项进行数值排序。例如,要按照第一列的数值大小对文件 file.txt 进行排序,可以使用以下命令:

sort -n -k 1 file.txt

-k 选项用于指定按照哪一列进行排序,这里指定按照第一列进行排序。

按月份排序

按照月份对文本进行排序,可以使用 -M 选项进行月份排序。例如,要按照第二列的月份大小对文件 file.txt 进行排序,可以使用以下命令:

sort -M -k 2 file.txt

按照时间戳排序

按照时间戳对文本进行排序,可以使用 -t-k 选项进行排序。例如,要按照第三列的时间戳大小对文件 file.txt 进行排序,可以使用以下命令:

sort -t ',' -k 3 file.txt

-t 选项用于指定分隔符,这里指定使用逗号作为分隔符。

k选项更深的用法

对于命令sort -t ' ' -k 1.2 a.txt,它使用sort命令对文件a.txt进行排序,具体解析如下:

  • -t ' ':这是sort命令的选项之一,用于指定字段的分隔符。在这里,使用空格作为字段分隔符。
  • -k 1.2:这是sort命令的另一个选项,用于指定排序的关键字。关键字由字段组成,指定字段的起始位置和结束位置。
    • 1.2表示排序关键字的起始位置和结束位置。在这里,1表示第一个字段,.表示字段内的字符位置,2表示字段的第二个字符。

根据这个解析,假设a.txt文件内容如下:

Mark Zuckerberg
Bill Gates
Jeff Bezos

运行命令sort -t ' ' -k 1.2 a.txt将按照每行的第一个字段的第二个字符进行排序。结果应该是:

Mark Zuckerberg
Jeff Bezos
Bill Gates

排序过程如下:

  1. 首先比较第一个字段的第二个字符,即比较 “a”、“e”、“i”。
  2. 根据字母顺序排序,得到的顺序是:“Mark Zuckerberg”、“Jeff Bezos”、“Bill Gates”。

因此,最终的排序结果应该是:

Mark Zuckerberg
Jeff Bezos
Bill Gates

在给定的命令sort -t ' ' -k 1.2 a.txt中,-k 1.2sort命令的选项之一,用于指定排序的关键字。

解析如下:

  • sort是一个用于对文本文件进行排序的Linux命令。
  • -t ' 'sort命令的选项,用于指定字段的分隔符。在这里,字段分隔符是空格。
  • -k 1.2sort命令的另一个选项,用于指定排序的关键字。关键字由字段组成,指定字段的起始位置和结束位置。

-k 1.2中:

  • 1.2指定了排序关键字的起始位置和结束位置。在这里,1表示第一个字段,.表示分隔符,2表示字段的第二个字符。
  • 通过使用1.2作为排序关键字,sort命令将基于每行的第一个字段的第二个字符进行排序。

例如,假设有以下文本内容的a.txt文件:

Mark Zuckerberg
Bill Gates
Jeff Bezos

运行命令sort -t ' ' -k 1.2 a.txt将按照每行的第一个字段的第二个字符进行排序。结果将如下所示:

Jeff Bezos
Mark Zuckerberg
Bill Gates

排序的顺序是基于每行第一个字段的第二个字符的字母顺序。在这个例子中,"Jeff Bezos"中的第一个字段是"Jeff",其第二个字符是"e""Mark Zuckerberg"中的第一个字段是"Mark",其第二个字符是"a""Bill Gates"中的第一个字段是"Bill",其第二个字符是"i"。根据第二个字符进行排序后,正确的结果应该是"Jeff Bezos"在前面。

练习

说明

1.过滤出/etc/passwd中用户名sc的用户,按照基本组id倒序排序输出
[root@localhost shell-test]# awk -F":" '$1~/sc/{print $0}' /etc/passwd
找出包含sc的用户名信息
[root@localhost shell-test]# cat /etc/passwd|grep sc|sort -n -k4 -r
[root@localhost shell-test]# awk -F":" '$1~/sc/{print $1,$4}' /etc/passwd|sort -n -k4 -r
这个也是一样的效果
2.统计出/var/log下,文件大小前五的以.log结尾的文件

xargs --配合管道符号一起使用

把前面命令的输出,变成后面命令的参数

[root@localhost 4-18]# find /var/log -type f -name "*.log"|xargs du -s|sort -r -n|head -5
1844	/var/log/audit/audit.log
1640	/var/log/anaconda/journal.log
1540	/var/log/vmware-vmsvc-root.log
224	/var/log/anaconda/packaging.log
88	/var/log/anaconda/storage.log

使用find命令也一样

[root@localhost 4-18]# find /var/log -type f -name "*.log" -exec du -s {} \;|sort -rn|head -5
1844	/var/log/audit/audit.log
1640	/var/log/anaconda/journal.log
1540	/var/log/vmware-vmsvc-root.log
224	/var/log/anaconda/packaging.log
88	/var/log/anaconda/storage.log

3.统计出当前网络连接总共有那些状态,每个状态有多少个?

[root@localhost shell-test]# netstat -atlnp|awk -F" " '{print $6}'|tail -n +3|sort|uniq -c
      2 ESTABLISHED
      1 Foreign
      8 LISTEN

4.统计scwebsite2_ssl.log日志文件中,访问量前10的ip

[root@localhost shell-test]# awk -F" " '{print $1}' scwebsite2_ssl.log|sort|uniq -c|sort -r -n|head 
    866 175.8.134.46
     62 42.200.114.225
     55 101.200.243.231
     17 128.199.116.195
     13 34.221.227.162
     10 47.92.31.65
     10 47.103.17.98
     10 47.101.53.251
     10 47.101.48.105
     10 47.101.203.216

5.系统监控的脚本

磁盘 根目录 --总大小,

题目说明,以及需要下载的插件

#发送邮件
yum install -y mailx sendmail
 echo "abc"|mail -s "test-mail" [email protected]



[root@sc-server shell-test]# yum install sysstat 



#系统监控的脚本
#告警邮件中  总大小,已用多少,使用率

#磁盘 根目录 -- 总大小,已用多少,使用率  。当使用率超过80%的时候就发送邮件告警。
    [root@sc-server shell-test]# df -Th
文件系统                类型      容量  已用  可用 已用% 挂载点
devtmpfs                devtmpfs  898M     0  898M    0% /dev
tmpfs                   tmpfs     910M     0  910M    0% /dev/shm
tmpfs                   tmpfs     910M   18M  893M    2% /run
tmpfs                   tmpfs     910M     0  910M    0% /sys/fs/cgroup
/dev/mapper/centos-root xfs        17G   11G  6.5G   63% /
/dev/sda1               xfs      1014M  151M  864M   15% /boot
tmpfs                   tmpfs     182M     0  182M    0% /run/user/0

#内存   查看使用率:  (total-available)/total   当使用率超过80%就发送告警邮件
[root@sc-server shell-test]# free -m
              total        used        free      shared  buff/cache   available
Mem:           1819         247        1011          17         559        1393
Swap:          2047           0        2047

#cpu 监控空闲  idle 小于百分之30就告警
[root@sc-server shell-test]# sar 1 1
Linux 3.10.0-1160.el7.x86_64 (sc-server) 	2023年04月18日 	_x86_64_	(2 CPU)

17时00分08秒     CPU     %user     %nice   %system   %iowait    %steal     %idle
17时00分09秒     all      0.00      0.00      0.00      0.00      0.00    100.00
平均时间:     all      0.00      0.00      0.00      0.00      0.00    100.00

提取磁盘使用情况

[root@localhost shell-test]# df -Th|tr -s " "|awk -F" " '$1~/root/{print $3,$4,$6}'
17G 2.9G 17%

提取内存使用情况

[root@localhost shell-test]# free -m|tr -s " "|awk -F" " '$1~/Mem/{print $2,$7}'
1819 1339

提前cup信息

[root@localhost shell-test]# sar 1 1|tr -s " "|awk -F" " '$1~/平均时间:/{print $8}'
100.00

mun=`echo $a|cut -c1-2

cat

介绍

在Shell中,cat命令用于显示文件内容,将文件的内容输出到标准输出设备(通常是终端)。

cat命令的基本语法如下:

cat [option] [file...]

cat命令支持的选项包括:

  • -n:在输出的每一行前面加上行号;
  • -b:在输出的非空行前面加上行号;
  • -s:将连续多个空行合并为一个空行输出;
  • -v:显示文件中的不可见字符(例如制表符和换行符)。

如果省略文件名,则cat命令从标准输入读取输入。如果指定一个或多个文件名,则cat命令按照指定的顺序依次输出每个文件的内容。

基本使用

在Shell中,cat是一个常用的命令行工具,用于将一个或多个文件的内容输出到终端或者重定向到另一个文件中。下面是cat命令的详细说明:

基本用法

cat命令的基本用法是将一个或多个文件的内容输出到终端。例如,执行以下命令可以将file.txt文件的内容输出到终端:

cat file.txt

如果要同时输出多个文件的内容,可以将它们的文件名依次列出:

cat file1.txt file2.txt file3.txt

这样会依次将file1.txtfile2.txtfile3.txt文件的内容输出到终端。

将多个文件合并输出

cat命令还可以将多个文件的内容合并输出到终端或重定向到一个文件中。例如,执行以下命令可以将file1.txtfile2.txt的内容合并输出到终端:

cat file1.txt file2.txt

如果要将多个文件的内容合并重定向到一个文件中,可以使用重定向符号>

cat file1.txt file2.txt > output.txt

这样会将file1.txtfile2.txt的内容合并并写入到output.txt文件中。

显示行号

cat命令还可以显示每一行的行号。例如,执行以下命令可以显示file.txt文件的每一行内容以及行号:

cat -n file.txt

其中,-n参数表示显示行号。

将特定行输出

cat命令还可以将文件的特定行输出到终端或重定向到另一个文件中。例如,执行以下命令可以将file.txt文件的第2行到第4行输出到终端:

cat file.txt | head -n 4 | tail -n 3

其中,head -n 4表示从file.txt文件中获取前4行,tail -n 3表示从前4行中获取最后3行,|表示将前一个命令的输出作为后一个命令的输入。

显示特殊字符

cat命令还可以显示特殊字符,例如制表符(\t)、回车符(\r)和换行符(\n)等。例如,执行以下命令可以显示file.txt文件的内容,并将制表符和换行符显示为可见字符:

cat -v file.txt

其中,-v参数表示显示特殊字符。

总结

cat命令是一个常用的命令行工具,用于将一个或多个文件的内容输出到终端或者重定向到另一个文件中。它还可以显示行号、将特定行输出、显示特殊字符等。cat命令的常用参数包括-n-v

需要注意的是,cat命令输出的内容可以通过重定向符(>>><等)进行重定向。例如,可以将cat命令输出的内容写入到文件中,或者将文件作为cat命令的输入。

实例

选项

cat -n 查看内容的时候,显示行号

cat查看文件的内容

concatenate 链接
standard output 标准输出–》输出到屏幕
standard input 标准输入 --》从键盘输入

[root@localhost lianxi]# cat rm.sh li.txt
#单纯将两个文件的输出在屏幕

[root@localhost lianxi]# cat rm.sh li.txt >sc.txt
#可以将两个文件合并成一个文件
# > 输出重定向  :作用将在屏幕上的输出重新定义输出到文件里 --》专门用来保存内容到文件里
				如果文件不存在就新建,如果存在,就覆盖原来文件内容

# >> 追加输出重定向:
	如果文件不存在就新建,如果存在,把新的内容追加到文件后面

split

split命令是一个在Unix、Linux和类Unix操作系统中常见的命令行实用程序,用于将一个大文件分割成多个较小的文件。以下是split命令的详细介绍:

语法

split命令的语法如下:

split [选项] 文件名 [输出文件名前缀]

其中,[选项]表示可选的命令行选项,文件名表示要分割的文件,[输出文件名前缀]表示生成的文件的文件名前缀。

常用选项

以下是split命令的一些常见选项:

  • -b: 按照指定的大小分割文件。可以使用K、M、G等后缀表示文件大小,例如10M表示分割成大小为10MB的文件。
  • -l: 按照行数分割文件。
  • -a: 指定生成的文件名后缀的长度,默认为2。
  • -d: 使用数字作为输出文件名的后缀。
  • -v: 使用版本号作为输出文件名的后缀。
  • -t: 在控制台输出分割进度信息。
  • --help: 显示帮助信息。
  • -C选项时,split会将输入文件分割成多个输出文件,每个输出文件的大小不超过指定的字节数.

-C-b的区别

我们通过一个例子具体说明有什么区别。

将passwd文件通过-b-C两种方式进行分割:

  1. 以b参数进行分割

    [root@localhost 5-8]# split -b 100 passwd -d san_
    
  2. 以C参数进行分割

    [root@localhost 5-8]# split -C 100 passwd -d Sc_
    

    可以看到san开头的文件比Sc文件少

[root@localhost 5-8]# ls
passwd  san_05  san_11  san_17  Sc_02  Sc_08  Sc_14  Sc_20  Sc_26
san_00  san_06  san_12  san_18  Sc_03  Sc_09  Sc_15  Sc_21
san_01  san_07  san_13  san_19  Sc_04  Sc_10  Sc_16  Sc_22
san_02  san_08  san_14  san_20  Sc_05  Sc_11  Sc_17  Sc_23
san_03  san_09  san_15  Sc_00   Sc_06  Sc_12  Sc_18  Sc_24
san_04  san_10  san_16  Sc_01   Sc_07  Sc_13  Sc_19  Sc_25

我们可以看看小文件是怎么样的

[root@localhost 5-8]# cat san_00
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nol
[root@localhost 5-8]# cat Sc_00
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin

当然我们也可以直接用diff查看文件是否相同

[root@localhost 5-8]# diff san_00 Sc_00
3d2
< daemon:x:2:2:daemon:/sbin:/sbin/nol
\ 文件尾没有 newline 字符

这个输出结果说明了两个文件的第三行不同。d2表示第二个文件删除了第三行,<符号后面是第一个文件中仅出现的文本。\符号后面是一个警告消息,说明第一个文件的最后一行没有换行符。

需要注意的是:虽然-b-C都是以字符为单位切割文件,但是-C会优先考虑整行的输出,多余的就不会放到这个文件里。

常见用法

以下是split命令的一些常见用法:

  • 分割文件并生成多个输出文件:提供-b-l选项和文件名前缀时,split命令将生成多个输出文件,每个文件大小或行数都符合指定的要求。

    split -b 10M file.txt output 
    # 将file.txt分割成大小为10MB的多个文件,以output为文件名前缀
    split -l 100 file.txt output
    # 将file.txt分割成每个文件100行的多个文件,以output为文件名前缀
    
  • 指定生成的文件名后缀长度:使用-a选项可以指定生成的文件名后缀的长度,默认为2。

    split -a 3 file.txt output
    # 将file.txt分割成多个文件,并使用3位数字作为文件名后缀,以output为文件名前缀
    
  • 指定生成的文件名格式:使用-d-v选项可以指定生成的文件名后缀格式。-d表示使用数字作为后缀

awk

介绍

awk 是一个文本处理工具,通常用于从文本文件中提取数据并对其进行处理。它是一种解释型语言,可以从标准输入或文件中读取数据,并对这些数据进行逐行处理

语法

awk options 'pattern { action }' filename

其中,options为可选参数。

pattern是一个正则表达式,用于匹配输入文件中的行。如果省略pattern,则默认匹配所有行。

action是一个或多个命令,用于在匹配到的行上执行操作。如果省略action,则默认打印匹配到的行。

filename是要处理的文件的名称。如果省略filename,则默认从标准输入读取数据。

awk 'BEGIN{commands}pattern{commands}END{commands}' file
  • BEGIN{commands}:处理数据前执行的命令
  • pattern{commands}:每行都执行的命令
  • END{commands}:处理数据后执行的命令

awk的命令执行过程

  1. 执行BEGIN{commands}语句块中的语句
  2. 从文件或stdin中读取第一行
  3. 有无模块匹配,若无执行{}中的语句,
  4. 若有则检查该行与patter是否匹配,若匹配,则执行{}中的语句。
  5. 若不匹配则不执行{}中的语句,接着读取下一行
  6. 重复这个过程,直到所有行被读取完毕
  7. 最后执行END{commands}语句块中的语句。
注意事项
awk -F分隔符 '/模式/{动作}' 输入文件

awk的指定一定要用单引号括起

awk的动作一定要用花括号括起

模式可以是正则表达式,条件表达式或两种组合

如果模块是正则表达式要用/定界符

多个动作之间用;号分开

例如:

在去匹配grade.txt文件之间先输出"你好",定义变量i的值为0,随后开始去匹配grade.txt文件每行的第一个字段是否含有li,如果含有li,输出该字段,同时变量i+1,在匹配完grade.txt文件的所有行后,输出"结束了",同时输出含有li的行数。

awk -F":" 'BEGIN{print "你好";i=0} $1 ~/li/{print
$1;i+=1}END{print "结束了" i}' grade.txt

不显示以h开头的行的第一列和第七列

[root@localhost shell-test]# awk -F: '/^[^h]/{print $1,$7}' /etc/p

选项

  • -F:指定输入字段分隔符。例如,-F:表示使用冒号作为字段分隔符。
  • -v:定义awk变量,可以在awk程序中使用。例如,-v var=value定义变量var,并设置其值为value。
  • -f:指定awk程序文件。例如,-f script.awk指定使用脚本文件script.awk作为awk程序。
  • -W:设置awk的行为。例如,-W posix启用POSIX兼容模式,-W traditional启用传统模式。
  • -S:启用seccomp沙箱模式,增强awk的安全性。

基本用法

先创建log.txt文本

[root@localhost 4-18]# vim log.txt
[root@localhost 4-18]# cat log.txt 
2 this is a test
3 Do you like awk
This's a test
10 There are orange,apple,mongo

用法一

awk '{[pattern] action}' {filenames}   # 行匹配语句 awk '' 只能用单引号

实例

# 每行按空格或TAB分割,输出文本中的1、4项
 $ awk '{print $1,$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # 格式化输出
 $ awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo

用法二:

awk -F  #-F相当于内置变量FS, 指定分割字符

实例:

# 使用","分割
 $  awk -F, '{print $1,$2}'   log.txt
 ---------------------------------------------
 2 this is a test
 3 Do you like awk
 This's a test
 10 There are orange apple
 # 或者使用内建变量
 $ awk 'BEGIN{FS=","} {print $1,$2}'     log.txt
 ---------------------------------------------
 2 this is a test
 3 Do you like awk
 This's a test
 10 There are orange apple
 # 使用多个分隔符.先使用空格分割,然后对分割结果再使用","分割
 $ awk -F '[ ,]'  '{print $1,$2,$5}'   log.txt
 ---------------------------------------------
 2 this test
 3 Are awk
 This's a
 10 There apple

用法三:

awk -v  # 设置变量

实例:

 $ awk -va=1 '{print $1,$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

用法四:

awk -f {awk脚本} {文件名}

实例:

 $ awk -f cal.awk log.txt

运算符

运算符 描述
= += -= *= /= %= ^= **= 赋值
?: C条件表达式
|| 逻辑或
&& 逻辑与
~ 和 !~ 匹配正则表达式和不匹配正则表达式
< <= > >= != == ~ ! 关系运算符
空格 连接
+ - 加,减
* / % 乘,除与求余
+ - ! 一元加,减和逻辑非
^ *** 求幂
++ – 增加或减少,作为前缀或后缀
$ 字段引用
in 数组成员

过滤第一列大于2的行

$ awk '$1>2' log.txt    #命令
#输出
3 Do you like awk
This's a test
10 There are orange,apple,mongo

过滤第一列等于2的行

$ awk '$1==2 {print $1,$3}' log.txt    #命令
#输出
2 is

过滤第一列大于2并且第二列等于’Are’的行

$ awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt    #命令
#输出
3 Are you

注意事项

&&||的优先级要高,||!要高

文本数据表达式: ==(精确匹配)

~波浪号表示匹配后的模式(模糊匹配)

例子:

有grade.txt文本如下:

[root@localhost shell-test]# cat grade.txt 
name 	chinese 	math 	english
xiaoming	80	90	99
lihua	89	70	99
yang	88	80	90
yangle	80	97	89

精确匹配每行第一个字段是yang的行

[root@localhost shell-test]# awk '$1 == "yang"{print $0}' grade.txt 
----------------------------------------------------
yang	88	80	90

模糊匹配每行第一个字段是yang的行

[root@localhost shell-test]# awk '$1 ~/yang/{print $0}' grade.txt 
------------------------------------------------
yang	88	80	90
yangle	80	97	89

内建变量

变量 描述
$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)

使用

使用正则,字符串匹配

# 输出第二列包含 "th",并打印第二列与第四列
$ awk '$2 ~ /th/ {print $2,$4}' log.txt
---------------------------------------------
this a
  • 表示模式开始。// 中是模式。
# 输出包含 "re" 的行
$ awk '/re/ ' log.txt
---------------------------------------------
3 Do you like awk
10 There are orange,apple,mongo
  • 忽略大小写
$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
---------------------------------------------
2 this is a test
This's a test
  • 模式取反
$ awk '$2 !~ /th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print $2,$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
  • 打印passwd文件中的第一列数据,以为分割符
[root@localhost shell-test]# awk -F":" '{print $1}' /etc/passwd

  • 显示每行的内容和行号

    [root@localhost shell-test]# awk -F: 'BEGIN{OFS="@"}/bash$/{print NR,$1,$7}' /etc/passwd
    1@root@/bin/bash
    21@bailongma@/bin/bash
    

    在 /etc/passwd 文件中查找包含 “bash” 字符串的行,并将它们的行号、用户名和默认 shell 以指定的格式输出

也可以和管道(|)连用,效果一样

[root@localhost shell-test]# cat /etc/passwd|awk -F":" '{print $1}'

打印最后一行

[root@localhost shell-test]# awk -F":" '{print $NF}' /etc/passwd
#打印最后一行

$1中过滤出含sc的第一列

[root@localhost shell-test]# awk -F":" '$1~/sc/{print $1}' /etc/passwd
  • 打印出grade.txt文件中的第三列数的和

    [root@localhost shell-test]# cat grade.txt 
    name 	chinese 	math 	english
    xiaoming	80	90	99
    lihua	89	70	99
    yang	88	80	90
    -------------------------------------------------
    [root@localhost shell-test]# awk 'NR>1{sum += $3}END{print sum}' grade.txt
    240
    

    还可以再求和前输出提示信息:

    [root@localhost shell-test]# awk 'BEGIN{print "数学总分数"}NR>1{sum += $3}END{print sum}' grade.txt
    数学总分数
    240
    

    打印数学成绩在80以上的学生姓名

    [root@localhost shell-test]#  awk 'BEGIN{print "数学总分数"}NR>1{sum += $3;if( $3>=80 ) print $1 }END{print sum}' grade.txt
    数学总分数
    xiaoming
    yang
    240
    
  • 打印出passwd用户名长度超过10的字段。

    [root@localhost shell-test]# awk -F: 'length($1)>10{print $0}' /etc/passwd
    systemd-network:x:192:192:systemd Network Management:/:/sbin/nologin
    

内置函数

在Shell中,awk是一种强大的文本处理工具,它支持使用函数对输入文本进行处理和转换。awk内置了一些常用的函数,同时也可以自定义函数来满足特定需求。下面是对awk函数的详细解释。

awk提供了一些内置函数,这些函数可以直接在awk程序中使用,无需额外定义。

一些常用的内置函数包括:

  • length(str):返回字符串str的长度。
  • substr(str, start, length):从字符串str中提取起始位置为start,长度为length的子字符串。
  • index(str, target):返回字符串str中第一次出现目标字符串target的位置。
  • split(str, array, sep):将字符串str按照分隔符sep分割成多个子字符串,并将结果存储在数组array中。
  • tolower(str):将字符串str中的大写字母转换为小写字母。
  • toupper(str):将字符串str中的小写字母转换为大写字母。
  • sprintf(format, expr1, expr2, ...):根据指定的格式字符串format,将表达式expr1expr2等转换为格式化的字符串。
  • int(expr):返回表达式expr的整数部分。
  • rand():生成一个0到1之间的随机数。
  • strftime():函数用于将时间戳转换为格式化的时间字符串。
  • systime():函数用于获取当前系统的时间戳。
  • system():函数用于执行Shell命令并返回命令的退出状态码

这只是一小部分awk的内置函数,还有其他许多函数可供使用。您可以参考awk的文档或手册以获取完整的内置函数列表。

自定义函数
除了内置函数,awk还支持定义自定义函数,以便在awk程序中使用。

自定义函数的语法如下:

function 函数名(参数列表) {
    函数体
    return 返回值
}

其中,函数名是自定义函数的名称,参数列表是函数接受的参数,函数体是函数的执行逻辑,返回值是可选的返回结果。

以下是一个示例,展示如何定义和使用自定义函数:

# 定义自定义函数
function multiply(x, y) {
    return x * y
}

# 使用自定义函数
{
    result = multiply($1, $2)
    print "结果:", result
}

上述示例定义了一个名为multiply的自定义函数,接受两个参数xy,并返回它们的乘积。在awk程序中,我们可以通过调用该函数来实现具体的计算。

split

在Shell脚本中,split是一个字符串处理函数,用于将一个字符串分割成子字符串,并将子字符串存储在一个数组中。下面是关于split函数的详细解释:

  1. 语法:
    split(string, array, separator)

    • string:要分割的字符串。
    • array:存储分割后的子字符串的数组。
    • separator:分割字符串的分隔符。可以是一个固定的字符或正则表达式。
  2. 功能:
    split函数将字符串按照指定的分隔符分割成多个子字符串,并将这些子字符串存储在数组中。分割后的子字符串可以根据索引访问,从1开始。

  3. 示例:
    下面是一个使用split函数的示例:

    str="apple,banana,orange"
    split(str, arr, ",")
    print arr[1]    # 输出 "apple"
    print arr[2]    # 输出 "banana"
    print arr[3]    # 输出 "orange"
    

    上面的示例中,str是要分割的字符串,arr是存储分割后子字符串的数组。使用逗号作为分隔符对字符串进行分割,然后可以通过索引访问数组中的元素。

  4. 分隔符:

    • 分隔符可以是一个固定的字符,例如空格、逗号、冒号等。
    • 分隔符也可以是一个正则表达式,用于更复杂的字符串分割。例如,使用空格和逗号作为分隔符:split(str, arr, "[ ,]")
  5. 返回值:
    split函数不返回任何值,它直接将分割后的子字符串存储在数组中。因此,它没有在条件语句中使用。

  6. 注意事项:

    • 如果数组已经包含元素,调用split函数会覆盖数组中的现有内容。
    • 如果分割后的子字符串数量超过数组的大小,额外的子字符串将被丢弃。

总结一下,split函数是Shell脚本中用于分割字符串的函数。它将字符串按照指定的分隔符分割成多个子字符串,并将子字符串存储在一个数组中,以便进一步处理和使用。

substr

在Shell脚本中,substr是一个用于提取字符串子串的函数。它允许你从一个字符串中选择指定位置的字符子串。下面是关于substr函数的详细解释:

  1. 语法:
    substr(string, start [, length])

    • string:要提取子串的源字符串。
    • start:子串的起始位置。如果是正数,则表示从左到右的索引;如果是负数,则表示从右到左的索引(-1表示最后一个字符)。
    • length:可选参数,表示子串的长度。如果省略,则提取从起始位置到字符串末尾的所有字符。
  2. 功能:
    substr函数用于提取字符串中的一个子串,可以根据起始位置和长度来确定提取的子串范围。

  3. 示例:
    下面是一些使用substr函数的示例:

    str="Hello, World!"
    echo $(substr(str, 1, 5))    # 输出 "Hello"
    echo $(substr(str, 8))       # 输出 "World!"
    echo $(substr(str, -6))      # 输出 "World!"
    

    上面的示例中,str是源字符串,使用substr函数从中提取了不同的子串。第一个示例提取了从索引1开始的前5个字符,第二个示例提取了从索引8开始到字符串末尾的所有字符,第三个示例提取了从右侧数第6个字符到末尾的所有字符。

    [root@localhost ~]# echo "hunan|shaoyang|dongkou|gaosha"|awk -F "|" '{print  substr($2,1,4)}'
    shao
    

    该命令的作用是对字符串"hunan|shaoyang|dongkou|gaosha"进行分割,并输出截取的第二个字段的前4个字符。

  4. 注意事项:

    • 起始位置和长度都可以是变量。
    • 如果起始位置超过了字符串的长度,substr函数将返回空字符串。
    • 如果起始位置为负数且绝对值超过了字符串的长度,substr函数将返回整个字符串。
    • 如果长度为负数,substr函数将从起始位置向前提取相应长度的子串。

总结一下,substr函数是Shell脚本中用于提取字符串子串的函数。它允许你根据起始位置和长度从一个字符串中选择指定位置的字符子串。这个函数在字符串处理和提取特定信息时非常有用。

使用

输出/etc/passwd文件中第一段字段中含有s的字符长度

[root@localhost 5-16]# awk -F: '$1 ~ /s/{print length($1)}' /etc/passwd

输出/etc/passwd文件中第二个字段长度为0的用户名,以及当前的日期

[root@localhost /]# awk -F: 'length($2) == 0 {print $1,"密码为空",strftime("%D",systime())}' /etc/passwd

将执行ls -l命令,并将命令的输出打印到标准输出。

awk '{ system("ls -l") }' file.txt

awk和grep结合使用

awk '{ status = system("grep -q pattern file.txt") } END { print "Exit status:", status }' file.txt

上面的命令将执行grep -q pattern file.txt命令,并将命令的退出状态码保存在status变量中。在END块中,它打印出命令的退出状态码。

需要注意的是,system函数返回的是命令的退出状态码,而不是命令的输出。通常,命令的退出状态码为0表示成功,非零值表示失败或错误。如果你需要获取命令的输出,可以使用管道(|)将命令的输出传递给awk,或者将命令的输出重定向到文件。

system函数中使用变量和字符串拼接来构建要执行的命令,以实现动态的命令执行。

awk -v pattern="$pattern" '{ system("grep " pattern " file.txt") }' file.txt

上面的命令中,$pattern是一个awk变量,它的值在命令执行之前被替换到命令中。

[root@localhost /]# awk -F: '{system("mkdir -p /yan/dong/sc"$1)}' /etc/passwd

该命令的作用是根据/etc/passwd文件的每一行的第一个字段,在/yan/dong路径下创建相应的子目录,并将/etc/passwd文件中的每个用户的用户名作为子目录名。

awk中的system函数用于执行命令并返回命令的退出状态码,它可以在awk脚本中实现与操作系统的交互。

awk函数的使用可以根据具体需求来选择合适的内置函数或自定义函数,以实现对文本的处理和转换操作。

awk中的if和for

当在Shell中使用awk时,if语句和for循环是非常有用的控制结构。它们允许您在awk脚本中执行条件判断和循环迭代操作。下面是对awk中if语句和for循环的超详细介绍和使用示例。

if语句

if语句允许您根据条件来执行不同的操作。

语法:

单分支

if (condition) statement

双分支

if (condition) statement1;statement2

多分支

if (条件) {
    操作
}
else if {
    操作
}
else{
	操作
}

示例:

# 根据条件判断输出结果
awk '{ if ($1 > 10) { print $1 " is greater than 10" } else { print $1 " is less than or equal to 10" } }' file.txt

在上述示例中,if语句用于判断第一个字段是否大于10,如果大于10,则输出相应的消息;否则输出另一个消息。

for循环

for循环允许您对数据进行迭代处理。

语法:

for (变量 in 数组/字符串) {
    操作
}

示例:

# 循环遍历数组元素并输出
awk 'BEGIN { fruits["apple"]="red"; fruits["banana"]="yellow"; fruits["orange"]="orange"; for (fruit in fruits) { print fruit " is " fruits[fruit] } }'

在上述示例中,for循环用于遍历数组fruits中的元素,并输出每个水果对应的颜色。

使用示例

下面是一个更完整的示例,结合了if语句和for循环,演示了如何在awk脚本中使用它们:

# 读取文件中的数字,并统计奇偶数的个数
awk '{
    if ($1 % 2 == 0) {
        even_count++
    } else {
        odd_count++
    }
}
END {
    print "Even numbers count: " even_count
    print "Odd numbers count: " odd_count
}' numbers.txt

在上述示例中,通过if语句判断每个数字是否为偶数,然后相应地增加even_countodd_count变量的计数。最后,在END块中打印统计结果。

这是一个简单的示例,但它展示了如何使用if语句和for循环在awk脚本中执行条件判断和循环迭代操作。根据实际需求,可以根据条件执行不同的操作,或对数据进行循环处理。

awk中的数组

在Shell脚本中,awk是一种功能强大的文本处理工具,它支持数组数据结构用于存储和处理数据。数组是一种有序的集合,可以通过索引来访问和操作其中的元素。下面是关于awk中数组的详细解释:

  1. 声明数组:在awk中,可以使用下面的语法来声明一个数组:

    array_name[index] = value
    

    其中,array_name是数组的名称,index是数组元素的索引(唯一),value是要存储的值。需要注意的是,awk中的数组是动态的,不需要提前指定数组的大小。

  2. 访问数组元素:可以使用下面的语法来访问数组中的元素:

    array_name[index]
    

    通过指定数组名称和索引,可以获取对应位置的元素的值。

  3. 遍历数组:可以使用for循环来遍历数组中的所有元素。下面是一个示例:

    awk 'BEGIN { array[1]="A"; array[2]="B"; array[3]="C"; for (i in array) { print array[i] } }'
    

    上面的命令将输出数组中的所有元素,即"A"、“B"和"C”。

  4. 数组长度:可以使用内置的length函数来获取数组的长度。下面是一个示例:

    awk 'BEGIN { array[1]="A"; array[2]="B"; array[3]="C"; print "Array length:", length(array) }'
    

    上面的命令将输出数组的长度,即3。

  5. 删除数组元素:可以使用delete关键字来删除数组中的元素。下面是一个示例:

    awk 'BEGIN { array[1]="A"; array[2]="B"; array[3]="C"; delete array[2]; for (i in array) { print array[i] } }'
    

    上面的命令将删除数组中索引为2的元素,并输出剩余的元素。

  6. 多维数组:awk还支持多维数组,即可以在数组的索引中使用多个值。下面是一个示例:

    awk 'BEGIN { array[1,1]="A"; array[1,2]="B"; array[2,1]="C"; for (i in array) { split(i, indices, SUBSEP); print indices[1], indices[2], array[i] } }'
    

    上面的命令定义了一个二维数组,并遍历输出所有元素及其索引。

  7. 对数组求和

    定义每个省的数据

[root@localhost /]# cat num.txt 
山东 aa 20
山东 bb 89
湖南 aa 12
湖北 aa 123
湖南 bb 143
湖北 bb 23
山西 aa 66
山西 bb 99

对同省的数据求和,同时输出每个省份的总数据

[root@localhost /]# awk '{pro[$1] += $3}END {for(i in pro) print i,pro[i]}' num.txt 
湖南 155
山西 165
山东 109
湖北 146

以上是关于awk中数组的详细解释。数组在awk中非常有用,可以用于存储和处理大量的数据,并进行各种操作,如遍历、添加、删除等。

paste

paste 是一个用于将多个文件按列合并的命令。它可以将多个文件的第一列合并成一个文件的第一列,第二列合并成一个文件的第二列,以此类推。paste 命令默认用制表符分隔不同文件的对应行,可以通过选项来指定分隔符。

以下是 paste 命令的一些常见用法和选项:

语法

paste [options] [file1 file2 ...]

选项

  • -d:指定分隔符,默认为制表符。
  • -s:将所有输入文件合并成一个文件,以行作为分隔符。

示例

  1. 将两个文件的第一列合并为一个文件的第一列:
$ paste file1 file2 > outputfile
  1. 使用逗号作为分隔符,将两个文件的第一列和第二列合并为一个文件的第一列和第二列:
$ paste -d',' file1 file2 > outputfile
  1. 将所有输入文件合并成一个文件,以行作为分隔符:
$ paste -s file1 file2 > outputfile

在合并文件方面,cat和paste文件的区别

[root@localhost 5-8]# cat grade.txt grade.txt 
name 	chinese 	math 	english
xiaoli	80	90	70
xiaohua	90	99	80
lihua	78	89	90

name 	chinese 	math 	english
xiaoli	80	90	70
xiaohua	90	99	80
lihua	78	89	90

[root@localhost 5-8]# paste grade.txt  grade.txt 
name 	chinese 	math 	english	name 	chinese 	math   english
xiaoli	80	90	70	xiaoli	80	90	70
xiaohua	90	99	80	xiaohua	90	99	80
lihua	78	89	90	lihua	78	89	90

cat 用于将文件内容打印到终端或合并文件,主要按行合并多个文件。而 paste 用于按合并多个文件。

join

join 是一个非常实用的命令,它可以将两个文件按照指定的字段连接起来,常用于数据处理和分析等任务。在这里,我们将详细介绍 join 命令的用法,以及一些常见的选项和示例。

命令语法

join 命令的基本语法如下:

join [options] file1 file2

其中,options 表示一些可选的参数,file1file2 表示要连接的两个文件的名称。

命令选项

join 命令有很多选项,下面是一些常用的选项:

  • -a FILENUM:打印指定文件的所有行,包括没有匹配到的行。FILENUM 表示要打印的文件编号,1 表示第一个文件,2 表示第二个文件,1 2 表示两个文件都要打印。
  • -e EMPTY:指定在缺少匹配行时要使用的空白字段值。
  • -i:忽略大小写进行匹配。
  • -t CHAR:指定字段分隔符。
  • -1 FIELD:指定第一个文件中用于连接的字段,从 1 开始计数。
  • -2 FIELD:指定第二个文件中用于连接的字段,从 1 开始计数。
  • -j 选项来指定连接的字段。

常见用法

接下来,我们将介绍 join 命令的常见用法和示例。

连接两个文件的行

默认情况下,join 命令会将两个文件中第一个字段相等的行连接起来。例如,我们有两个文件 file1.txtfile2.txt,它们的内容如下:

$ cat file1.txt
1 John
2 Mary
3 Tom

$ cat file2.txt
1 M
2 F
4 M

我们可以使用以下命令将它们连接起来:

$ join file1.txt file2.txt
1 John M
2 Mary F

连接的结果为两个文件中第一个字段相等的行,第二个字段会合并在一起,使用空格分隔。

指定连接的字段

如果要指定连接的字段,可以使用 -1-2 选项。例如,如果要按照第二个字段连接两个文件:

$ join -1 2 -2 2 file1.txt file2.txt
John 1 M
Mary 2 F

如果要按照第一个字段连接两个文件:

$ join -1 1 -2 1 file1.txt file2.txt
1 John M
2 Mary F

打印没有匹配到的行

默认情况下,join 命令只打印两个文件中都匹配到的行。如果要打印没有匹配到的行,可以使用 -a 选项。例如,如果要打印第一个文件中所有的行,包括没有匹配到的行:

$ join -a 1 file1.txt file2.txt
1 John M
2 Mary F
3 Tom

如果要打印第二个文件中所有的行,包括没有匹配到的行:

$ join -a 2 file1.txt file2.txt
1 John M
2 Mary F
4 M

指定空白字段值

如果没有匹配到行,join 命令会使用空白字段值填充缺失的字段。可以使用 -e 选项指定要使用的空白字段值。例如,如果要使用 NA 作为空白字段值:

$ join -e NA file1.txt file2.txt
1 John M
2 Mary F
3 Tom NA

忽略大小写进行匹配

如果想要忽略大小写进行匹配,可以使用 -i 选项。例如,如果要按照第一个字段忽略大小写连接两个文件:

$ join -i -1 1 -2 1 file1.txt file2.txt
1 John M
2 Mary F

指定字段分隔符

如果文件中的字段使用了不同的分隔符,可以使用 -t 选项指定分隔符。例如,如果文件中的字段使用了冒号作为分隔符:

$ cat file1.txt
1:John
2:Mary
3:Tom

$ cat file2.txt
1:M
2:F
4:M

$ join -t: file1.txt file2.txt
1:John:M
2:Mary:F

处理大文件

如果要处理大文件,可以使用 sort 命令对文件进行排序,以减少 join 命令的运行时间。例如,如果要处理两个非常大的文件:

$ sort file1.txt > file1.sorted.txt
$ sort file2.txt > file2.sorted.txt
$ join file1.sorted.txt file2.sorted.txt

在这个例子中,我们将文件先排序,再使用 join 命令进行连接。这样做可以减少 join 命令的运行时间和内存占用。

根据单个字段进行连接

假设有两个文件,分别为 file1.txtfile2.txt,内容如下:

$ cat file1.txt
1 John
2 Mary
3 Tom

$ cat file2.txt
1 M
2 F
4 M

如果要根据第一个字段连接两个文件,可以使用 -j 选项:

$ join -j 1 file1.txt file2.txt
1 John M
2 Mary F

在这个例子中,我们使用 -j 1 选项指定第一个字段作为连接字段。join 命令会根据第一个字段将两个文件连接起来。

根据多个字段进行连接

假设有两个文件,分别为 file1.txtfile2.txt,内容如下:

$ cat file1.txt
1 John M
2 Mary F
3 Tom

$ cat file2.txt
1 New York
2 San Francisco
4 Seattle

如果要根据第一个和第二个字段连接两个文件,可以使用 -j 选项:

$ join -j 1.2 file1.txt file2.txt
1 John M New York
2 Mary F San Francisco

在这个例子中,我们使用 -j 1.2 选项指定第一个和第二个字段作为连接字段。join 命令会根据第一个和第二个字段将两个文件连接起来。

根据字段名进行连接

假设有两个文件,分别为 file1.txtfile2.txt,内容如下:

$ cat file1.txt
id name gender
1 John M
2 Mary F
3 Tom 

$ cat file2.txt
id city
1 New York
2 San Francisco
4 Seattle

如果要根据 id 字段连接两个文件,可以使用 -j 选项:

$ join -j id file1.txt file2.txt
id name gender city
1 John M New York
2 Mary F San Francisco

在这个例子中,我们使用 -j id 选项指定 id 字段作为连接字段。join 命令会根据 id 字段将两个文件连接起来。

注意事项

使用 `-j选项连接文件时,需要注意以下几点:

  • 如果指定的连接字段在某个文件中不存在,则该文件中相应的行会被忽略。
  • 如果两个文件中有多个字段的值相同,则会将它们全部连接起来,从而生成多列输出。
  • 如果两个文件中有多个匹配行,则会为每一组匹配行生成一行输出。
  • 如果指定的连接字段包含空格或其他特殊字符,需要使用引号将其括起来。

在实际使用中,根据具体的需求和数据格式,灵活使用 -j 选项可以更加方便和高效地处理文件连接问题。

总结

join 命令是一个非常实用的工具,它可以将两个文件按照指定的字段连接起来。在实际使用中,我们需要根据具体的需求选择不同的选项,并且需要注意文件中的字段分隔符和大小写等问题。

sed

介绍

Sed(Stream Editor)是一个功能强大的文本处理工具,是一种支持正则表达式的非交互式交流编辑器,常用于在命令行中对文本进行编辑和转换。它通过逐行读取输入文本并应用一系列编辑命令来修改文本内容。

sed 查找的时候

  • 根据行号
  • 根据字符串 --》 模式匹配

基本语

sed [选项] [脚本] [输入文件]
shell 命令|sed[选项] sed编辑命令
sed[选项] -f sed脚本文件 输入文件

选项

  • -e:允许在命令行中指定多个编辑脚本。
  • -f:从指定文件中读取编辑脚本。
  • -i:直接修改输入文件,而不是将输出打印到标准输出。
  • -n:禁止自动打印模式空间的内容,只有使用p命令显示指定的行。
  • -r:支持扩展正则表达式

脚本:
sed脚本由一系列的编辑命令组成,每个命令可以单独使用或按顺序组合。命令可以使用数字或正则表达式来指定匹配的行,然后对匹配行进行操作。

动作

  • p:打印当前行或指定行。

  • d:删除当前行或指定行。

  • s/原字符串/新字符串/:用新字符串替换匹配的原字符串。可以使用正则表达式进行模式匹配,可以使用任意分割符作为定界符。

  • i:在当前行前插入文本。

  • a:在当前行后追加文本。

  • **c**:用新文本替换当前行。

  • r 文件:从指定文件中读取文本并将其插入到当前行后面。

  • **w 文件**:将匹配的行写入到指定文件中。

  • **=**:输出行号

  • h 拷贝模板块的内容到内存中的缓冲区。

  • H 追加模板块的内容到内存中的缓冲区。

  • g 获得内存缓冲区的内容,并替代当前模板块中的文本。

  • G 获得内存缓冲区的内容,并追加到当前模板块文本的后面。

  • x 表示互换模板块中的文本和缓冲区中的文本。

正则

^ # 匹配行开始,如:/^sed/匹配所有以sed开头的行。
$ # 匹配行结束,如:/sed$/匹配所有以sed结尾的行。
. # 匹配一个非换行符的任意字符,如:/s.d/匹配s后接一个任意字符,最后是d。
* # 匹配0个或多个字符,如:/*sed/匹配所有模板是一个或多个空格后紧跟sed的行。
[] # 匹配一个指定范围内的字符,如/[sS]ed/匹配sed和Sed。  
[^] # 匹配一个不在指定范围内的字符,如:/[^A-RT-Z]ed/匹配不包含A-R和T-Z的一个字母开头,紧跟ed的行。
\(..\) # 匹配子串,保存匹配的字符,如s/\(love\)able/\1rs,loveable被替换成lovers。
& # 保存搜索字符用来替换其他字符,如s/love/ **&** /,love这成 **love** 。
\< # 匹配单词的开始,如:/\ # 匹配单词的结束,如/love\>/匹配包含以love结尾的单词的行。
x\{m\} # 重复字符x,m次,如:/0\{5\}/匹配包含5个0的行。
x\{m,\} # 重复字符x,至少m次,如:/0\{5,\}/匹配至少有5个0的行。
x\{m,n\} # 重复字符x,至少m次,不多于n次,如:/0\{5,10\}/匹配5~10个0的行。  

地址选择:

  • n:只对匹配模式的行执行后续命令。
  • 1,3:选择1到3行。
  • /pattern/:选择匹配正则表达式模式的行。
  • !:选择不匹配模式的行。

模式空间:

sed 默认不会直接修改源文件数据,而是会将数据复制到缓冲区中,修改也仅限于缓冲区中的数据

  • 模式空间是sed用来存储当前处理行内容的缓冲区。

  • 默认情况下,每一行读取到模式空间中,并执行相应的命令。

  • 可以使用n命令从输入中读取下一行并替换当前行,或使用p命令打印当前行。

  • 可以使用h(覆盖)和H(追加)命令将模式空间中的内容复制到保持空间(hold space)中。

  • 可以使用g(覆盖)和G(追加)命令将保持空间中的内容复制到模式空间中。

替换标记:

  • 默认情况下,s命令只替换每行的第一个匹配项。可以使用g标记替换所有匹配项。
  • 可以使用数字标记替换特定位置的匹配项。

用法:

  1. 将文件中的old替换为new

    `sed 's/old/new/g' file.txt`
    

    sed ‘s/old/new/’ file.txt 匹配每一行的第一个old替换为new

    `sed 's/old/new/2' file.txt`
    

    sed 编辑器只替换每行中第 2 次出现的匹配模式

    `sed 's/old/new/g' file.txt`
    
    [root@localhost 5-17]# sed -i 's/8.8.8.8/192.168.242.144/g' ip.txt
    

    该命令将ip.txt文件中的8.8.8.8全部换成192.168.242.144.

  2. 删除文件中的空行:

    `sed '/^$/d' file.txt
    
  3. 打印文件的第5行:

    `sed -n '5p' file.txt`
    
    [root@localhost 5-17]# sed -n '2,3p' ip.txt
    zhong  192.168.242.144 li 192.168.242.144
    zhong  192.168.242.144 li 192.168.242.144
    

    显示 ip.txt文件中的2,3行

    [root@localhost 5-17]# sed -n '2,3!p' ip.txt
    zhong  192.168.242.144 li 192.168.242.144
    zhong  192.168.242.144 li 192.168.242.144
    zhong  192.168.242.144 li 192.168.242.144
    

    输出ip.txt文化部中的除2,3行的其他行

    [root@localhost 5-17]# sed -n '1,+2p' ip.txt
    

    显示123行

    [root@localhost 5-17]# sed -n '1p;3p;5p' ip.txt
    

    显示1,3,5行的内容

    [root@localhost 5-17]# cat -n /etc/passwd|sed -n -e '3p' -e '5p'
    

    该命令的作用是从/etc/passwd文件中读取内容,并使用sed命令只打印第3行和第5行,同时显示行号。这样,你将会看到/etc/passwd文件中第3行和第5行的内容以及它们所在的行号。

    [root@localhost 5-17]# cat -n /etc/passwd|sed -n '2~2p'
    

    该命令的作用是从/etc/passwd文件中读取内容,并使用sed命令打印从第2行开始的每隔2行的内容。这样,你将会看到/etc/passwd文件中的偶数行内容以及它们所在的行号。

  4. 在文件的第3行后插入一行文本:

    `sed '3a\New line' file.txt`
    
  5. 将文件的第2行替换为其他文本:

    `sed '2c\Replacement text' file.txt
    
  6. 统计一段时间内的ip访问量

[root@localhost 5-17]# sed -n '/09\/Jan\/2023:22:22:22/,/19\/Jan\/2023:23:23:23/p' access.log

这个命令的意思是从"access.log"文件中提取出在时间范围为"09/Jan/2023:22:22:22"到"19/Jan/2023:23:23:23"之间的内容,并将结果输出。sed命令是一个流编辑器,使用-n参数表示只输出匹配的行,/pattern1/,/pattern2/表示选择从pattern1匹配的行到pattern2匹配的行之间的内容,p表示打印匹配的行。所以,这个命令会输出在给定时间范围内的日志记录。

sed中标签的用法

[root@localhost 6-1]# sed -i -r 's/(^[0-Z]+)(.*)/\2/' passwd
[root@localhost 6-1]# tail -2 passwd
:x:38:38::/etc/ntp:/sbin/nologin
:x:6688:6688:wudangpai:/home/hellow:/bin/bash

上述命令的目的是在 passwd 文件中对每行进行替换操作。如果行以大写字母或数字开头,将该开头部分删除,保留后续的内容。

[root@localhost 6-1]# sed -i -r 's/(^[0-Z]+)(.*)/\1/' passwd
[root@localhost 6-1]# tail -2 passwd
ntp
hellow

a和i的用法

[root@localhost 6-1]# sed -i '2a hhhh' a.txt 
[root@localhost 6-1]# cat a.txt 
nihao
hello 
hhhh
world
ni
wo
ta
[root@localhost 6-1]# sed -i '/hello/a wwww' a.txt 
[root@localhost 6-1]# cat a.txt 
nihao
hello 
wwww
hhhh
world
ni
wo
ta

上述命令的目的是对输入流中的每一行进行处理,并在匹配到包含 “hello” 的行的后面插入新的文本行 “wwww”。

/hello/ 正则表达式用于匹配包含 “hello” 的文本行。a 命令标记用于指示在匹配行的后面插入新的文本。插入操作将在匹配行的下方插入 “wwww”。

该命令会直接修改 a.txt文件中的内容,将插入结果写回原始文件

[root@localhost 6-1]# sed -i '/hello/i wwww' a.txt 
[root@localhost 6-1]# cat a.txt 
nihao
wwww
hello 
wwww
hhhh
world
ni
wo
ta

上述命令的目的是在 a.txt 文件中,在包含 “hello” 的行的前面插入新的文本行 “wwww”。

/hello/ 正则表达式用于匹配包含 “hello” 的文本行。i 命令标记用于指示在匹配行的前面插入新的文本。插入操作将在匹配行的上方插入 “wwww”。

该命令会直接修改 a.txt 文件中的内容,将插入结果写回原始文件。

难一点的运用

0.0.0.0 1.1.1.1 变为0.0.0.0:80,1.1.1.1:80,2.2.2.2:80
2.2.2.2

[root@localhost 6-2]# cat text.txt 
0.0.0.0
1.1.1.1
2.2.2.2
[root@localhost 6-2]# cat text.txt|sed -n 's/$/:80/;H;${x;s/\n/,/2g;p}'
0.0.0.0:80,1.1.1.1:80,2.2.2.2:80

用xargs更简单

[root@localhost 6-2]# cat text.txt |xargs
0.0.0.0 1.1.1.1 2.2.2.2
[root@localhost 6-2]# cat text.txt |xargs|awk '{print $1 ":80",$2 ":80",$3 ":80"}'
0.0.0.0:80 1.1.1.1:80 2.2.2.2:80

另一种解法

[root@localhost 6-2]# cat text.txt|sed -n 'N;N;s/\n/:80,/g;s/$/:80/p'
0.0.0.0:80,1.1.1.1:80,2.2.2.2:80

注意事项:

sed后接i与不接i的区别:

[root@localhost 5-17]# cat ip.txt |sed 's/xiao/da/g'
da  192.168.242.144 li 192.168.242.144
da  192.168.242.144 li 192.168.242.144
da  192.168.242.144 li 192.168.242.144
da  192.168.242.144 li 192.168.242.144
da  192.168.242.144 li 192.168.242.144
[root@localhost 5-17]# cat ip.txt |sed -i 's/xiao/da/g'
sed: 没有输入文件
[root@localhost 5-17]# sed -i 's/xiao/zhong/g' ip.txt
[root@localhost 5-17]# cat ip.txt
zhong  192.168.242.144 li 192.168.242.144
zhong  192.168.242.144 li 192.168.242.144
zhong  192.168.242.144 li 192.168.242.144
zhong  192.168.242.144 li 192.168.242.144
zhong  192.168.242.144 li 192.168.242.144

sed 后接了选项i后,需要接修改文件,修改的结果不会展示在屏幕上,而在管道中使用sed不要接修改文件,会通过管道把文件传给sed,同时,会把修改内容直接输出在屏幕上。最突出的就是sed通过管道的操作,不会影响原文件。

  • sed和grep的对比
[root@localhost 6-1]# df -h|sed -n "/\/$/p"
/dev/mapper/centos-root   17G  3.2G   14G   19% /
[root@localhost 6-1]# df -h|grep "/$"
/dev/mapper/centos-root   17G  3.2G   14G   19% /

该命令的目的是过滤并只显示文件系统挂载点的行,这些挂载点以斜杠 / 结尾。

sed单引号和双引号的区别:
  • 双引号里可以使用shell变量

  • 单引号不可以

  • 单引号和双引号里都可以存放模式

    [root@localhost 5-17]# cat -n /etc/passwd|sed -n "${num1}p;${num2}p"
         5	lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
        10	operator:x:11:0:operator:/root:/sbin/nologin
    
    [root@localhost 5-17]# cat -n /etc/passwd|sed -n '${num1}p;${num2}p'
    sed:-e 表达式 #1,字符 4:命令后含有多余的字符
    

你可能感兴趣的:(linux,linux,笔记,正则表达式)