Linux 正则表达式 ⑪

正则表达式

1.Linux grep 命令

Linux grep (global regular expression) 命令用于查找文件里符合条件的字符串或正则表达式。

grep 指令用于查找内容包含指定的范本样式的文件,如果发现某文件的内容符合所指定的范本样式,预设 grep 指令会把含有范本样式的那一列显示出来。若不指定任何文件名称,或是所给予的文件名为 -,则 grep 指令会从标准输入设备读取数据。

语法

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

常用参数

更多参数

以下是按照要求为每个案例分别创建所需文件或目录后再执行相应操作的详细脚本:

案例 1:在文件 file.txt 中查找字符串 "hello",并打印匹配的行

bash 复制代码
# 创建 file.txt 文件并添加包含 "hello" 的内容
if [! -f file.txt ]; then
    echo "This line has hello in it" > file.txt
fi

# 在 file.txt 中查找 "hello" 并打印匹配行
echo "案例 1:在文件 file.txt 中查找字符串 \"hello\",并打印匹配的行"
grep hello file.txt
echo ""

案例 2:在文件夹 dir 中递归查找所有文件中匹配正则表达式 "pattern" 的行,并打印匹配行所在的文件名和行号

bash 复制代码
# 创建 dir 目录及包含 "pattern" 的文件
if [! -d dir ]; then
    mkdir dir
    touch dir/file_with_pattern.txt
    echo "This line contains the pattern" > dir/file_with_pattern.txt
fi

# 在 dir 目录中递归查找 "pattern" 并打印匹配信息
echo "案例 2:在文件夹 dir 中递归查找所有文件中匹配正则表达式 \"pattern\" 的行,并打印匹配行所在的文件名和行号"
grep -r -n pattern dir/
echo ""

案例 3:在标准输入中查找字符串 "world",并只打印匹配的行数

bash 复制代码
# 此案例无需创建文件,直接操作
echo "案例 3:在标准输入中查找字符串 \"world\",并只打印匹配的行数"
echo "hello world" | grep -c world
echo ""

案例 4:在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行

bash 复制代码
# 创建后缀有 file 字样且包含 test 的文件
if [! -f testfile1 ]; then
    touch testfile1
    echo "This a Linux testfile!" > testfile1
fi
if [! -f testfile_2 ]; then
    touch testfile_2
    echo "This is a linux testfile!" > testfile_2
    echo "Linux test" >> testfile_2
fi

# 在相关文件中查找 "test" 并打印匹配行
echo "案例 4:在当前目录中,查找后缀有 file 字样的文件中包含 test 字符串的文件,并打印出该字符串的行"
grep test *file 
echo ""

案例 5

bash 复制代码
# 创建 /etc/acpi 目录及示例文件
sudo mkdir -p /etc/acpi
file_path="/etc/acpi/update_file.txt"
if [! -f $file_path ]; then
    sudo touch $file_path
    sudo echo "This line has update" > $file_path
fi
# 在 /etc/acpi 目录及其子目录中递归查找 "update" 并打印匹配行
echo "案例 5:以递归的方式查找指定目录 /etc/acpi 及其子目录下所有文件中包含字符串 \"update\" 的文件,并打印出该字符串所在行的内容"
grep -r update /etc/acpi  
echo ""

案例 6

bash 复制代码
# 创建相关文件
file1="testfile1"
file2="testfile2"
if [! -f $file1 ]; then
    touch $file1
    echo "No test here" > $file1
fi
if [! -f $file2 ]; then
    touch $file2
    echo "Just a simple line" > $file2
fi
# 在相关文件中反向查找不包含 "test" 的行并打印
echo "案例 6:反向查找,查找文件名中包含 test 的文件中不包含 test 的行"
grep -v test *test*

2.Linux awk 命令

awk 是一种处理文本文件的语言,是一个强大的文本分析工具。

awk 通过提供编程语言的功能,如变量、数学运算、字符串处理等,使得对文本文件的分析和操作变得非常灵活和高效。

之所以叫 awk 是因为其取了三位创始人 Alfred Aho,Peter Weinberger, 和 Brian Kernighan 的 Family Name 的首字符。

语法

bash 复制代码
awk options 'pattern {action}' file

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

以下将从创建文件开始,对每个 awk 命令用法案例进行单独讲解:

1. 创建测试文件

首先,创建一个用于测试的文件 file,并添加一些示例数据,以便后续演示 awk 的各种用法。

bash 复制代码
#!/bin/bash

# 创建测试文件 file 并写入示例数据
echo "apple,3,5
banana,4,7
cherry,2,6
date,5,9" > file

2. 案例 1:打印整行

bash 复制代码
echo "案例 1:打印整行"
awk '{print}' file
echo ""

解释

  • awk 是一个强大的文本处理工具,用于处理文本文件中的数据。
  • 在这个命令中,{print}awk 的操作部分。print 是一个内置函数,用于输出内容。
  • 由于没有指定任何特定的列或条件,awk 会默认对文件 file 中的每一行进行操作,将整行内容原样输出。

3. 案例 2:打印特定列

bash 复制代码
echo "案例 2:打印特定列"
awk '{print $1, $2}' file
echo ""

解释

  • {print $1, $2}awk 的操作部分。$1$2 分别表示文件中每行按默认分隔符(空格或制表符)分割后的第一列和第二列。
  • awk 会读取文件 file 的每一行,将其按默认分隔符分割成列,然后输出第一列和第二列的内容。在我们创建的文件中,这将输出水果名称和对应的数量。

4. 案例 3:使用分隔符指定列

bash 复制代码
echo "案例 3:使用分隔符指定列"
awk -F',' '{print $1, $2}' file
echo ""

解释

  • -F','awk 的选项,用于指定字段分隔符。这里指定逗号 , 为分隔符。
  • {print $1, $2} 表示输出按指定分隔符(逗号)分割后的第一列和第二列。
  • 这样,awk 会将文件 file 中的每一行按逗号分割,然后输出第一列(水果名称)和第二列(数量)。

5. 案例 4:打印行数

bash 复制代码
echo "案例 4:打印行数"
awk '{print NR, $0}' file
echo ""

解释

  • NRawk 中的一个内置变量,代表当前处理的行号。
  • $0 也是一个内置变量,代表当前处理的整行内容。
  • {print NR, $0} 表示 awk 在处理文件 file 的每一行时,会输出该行的行号和整行内容。这样可以方便地查看每一行在文件中的位置以及具体内容。

6. 案例 5:打印行数满足条件的行

bash 复制代码
echo "案例 5:打印行数满足条件的行"
awk '/banana/ {print NR, $0}' file
echo ""

解释

  • /banana/ 是一个正则表达式模式,用于匹配包含字符串 banana 的行。
  • {print NR, $0} 表示当某一行匹配到 banana 这个模式时,awk 会输出该行的行号 NR 和整行内容 $0
  • 在文件 file 中,只有包含 banana 的那一行会被匹配并输出其行号和内容。

7. 案例 6:计算列的总和

bash 复制代码
echo "案例 6:计算列的总和"
awk '{sum += $2} END {print sum}' file
echo ""

解释

  • {sum += $2}:在处理文件 file 的每一行时,awk 会将变量 sum 初始化为 0(如果未定义),然后将每一行的第二列值累加到 sum 中。这里的 $2 表示按默认分隔符分割后的第二列。
  • ENDawk 中的一个特殊块,当文件所有行处理完毕后,会执行 END 块中的内容。
  • {print sum}END 块中,用于输出累加后的总和。因此,这个命令会计算文件中第二列所有数值的总和。

8. 案例 7:打印最大值

bash 复制代码
echo "案例 7:打印最大值"
awk 'max < $2 {max = $2} END {print max}' file
echo ""

解释

  • max < $2 {max = $2}:在处理文件 file 的每一行时,awk 会将当前行的第二列值 $2 与变量 max 进行比较。如果 $2 大于 max,则将 max 更新为 $2。在处理第一行时,max 会被初始化为第一行的第二列值。
  • END 块在文件所有行处理完毕后执行。
  • {print max}END 块中,用于输出经过比较和更新后的 max 值,即文件中第二列的最大值。

9. 案例 8:格式化输出

bash 复制代码
echo "案例 8:格式化输出"
awk '{printf "%-10s %-10s\n", $1, $2}' file

解释

  • printfawk 中的一个格式化输出函数,类似于 C 语言中的 printf
  • %-10s 表示左对齐,宽度为 10 个字符的字符串格式。这里第一个 %-10s 用于格式化输出第一列 $1,第二个 %-10s 用于格式化输出第二列 $2
  • \n 表示换行,确保每一行输出后换行。
  • 这个命令会按照指定的格式输出文件 file 中的每一行,使输出结果更加整齐美观。

清理测试文件

在所有案例演示完毕后,为了保持环境整洁,可以删除测试文件 file

bash 复制代码
rm -f file

使用方法

  1. 将上述代码保存为一个脚本文件,例如 awk_demos.sh
  2. 为脚本文件添加执行权限:chmod +x awk_demos.sh
  3. 运行脚本:./awk_demos.sh,观察每个案例的输出结果。

通过以上详细的讲解和示例,你可以更深入地理解和掌握 awk 的各种常见用法。


基本用法

以下将从创建文件开始,对每个 awk 用法案例进行详细分开讲解:

1. 创建测试文件

首先,创建一个名为 log.txt 的测试文件,并添加一些示例数据,用于后续的 awk 操作演示。

bash 复制代码
#!/bin/bash

# 创建 log.txt 文件并添加内容
echo "2 this is a test
3 Do you like awk
This's a test
10 There are orange,apple,mongo" > log.txt

2. 用法一:awk '{[pattern] action}' {filenames}

这种形式下,awk 会按默认的分隔符(空格或制表符)对每行进行分割,然后根据指定的 action 进行操作。

实例 1:输出文本中的第 1、4 项
bash 复制代码
echo "案例 1:用法一 - 实例 1:输出文本中的第 1、4 项"
awk '{print $1,$4}' log.txt
echo "---------------------------------------------"

代码解释

  • awk '{print $1,$4}' log.txt:这行命令中,awk 是命令本身,{print $1,$4} 是操作部分。printawk 的打印函数,$1$4 分别表示每行按默认分隔符(空格或制表符)分割后的第 1 列和第 4 列。log.txt 是要处理的文件名。
实例 2:格式化输出
bash 复制代码
echo "案例 1:用法一 - 实例 2:格式化输出"
awk '{printf "%-8s %-10s\n",$1,$4}' log.txt
echo "---------------------------------------------"

代码解释

  • awk '{printf "%-8s %-10s\n",$1,$4}' log.txt:这里使用了 printf 函数进行格式化输出。%-8s 表示左对齐,宽度为 8 个字符的字符串格式;%-10s 表示左对齐,宽度为 10 个字符的字符串格式。\n 表示换行。$1$4 同样是每行按默认分隔符分割后的第 1 列和第 4 列。

3. 用法二:awk -F

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

实例 1:使用 , 分割
bash 复制代码
echo "案例 2:用法二 - 实例 1:使用, 分割"
awk -F, '{print $1,$2}' log.txt
echo "---------------------------------------------"

代码解释

  • awk -F, '{print $1,$2}' log.txt-F, 表示将逗号 , 设置为字段分隔符。{print $1,$2} 表示打印按逗号分割后的第 1 列和第 2 列。
实例 2:使用内建变量 FS
bash 复制代码
echo "案例 2:用法二 - 实例 2:使用内建变量 FS"
awk 'BEGIN{FS=","} {print $1,$2}' log.txt
echo "---------------------------------------------"

代码解释

  • awk 'BEGIN{FS=","} {print $1,$2}' log.txtBEGIN 块在处理文件内容之前执行,在这里将 FS(字段分隔符)设置为逗号 ,。然后 {print $1,$2} 打印按逗号分割后的第 1 列和第 2 列。
实例 3:使用多个分隔符
bash 复制代码
echo "案例 2:用法二 - 实例 3:使用多个分隔符"
awk -F '[,]' '{print $1,$2,$5}' log.txt
echo "---------------------------------------------"

代码解释

  • awk -F '[,]' '{print $1,$2,$5}' log.txt-F '[,]' 表示使用空格或逗号作为分隔符。{print $1,$2,$5} 表示打印按此分隔符分割后的第 1 列、第 2 列和第 5 列。

4. 用法三:awk -v

-v 用于设置变量,在 awk 脚本中可以使用这些自定义变量。

实例 1:设置单个变量
bash 复制代码
echo "案例 3:用法三 - 实例 1:设置单个变量"
awk -va=1 '{print $1,$1+a}' log.txt
echo "---------------------------------------------"

代码解释

  • awk -va=1 '{print $1,$1+a}' log.txt-va=1 表示设置一个名为 a 的变量,其值为 1。{print $1,$1+a} 表示打印每行按默认分隔符分割后的第 1 列的值,以及第 1 列的值加上变量 a 的结果。
实例 2:设置多个变量
bash 复制代码
echo "案例 3:用法三 - 实例 2:设置多个变量"
awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt
echo "---------------------------------------------"

代码解释

  • awk -va=1 -vb=s '{print $1,$1+a,$1b}' log.txt-va=1 设置变量 a 的值为 1,-vb=s 设置变量 b 的值为 s{print $1,$1+a,$1b} 表示打印每行按默认分隔符分割后的第 1 列的值、第 1 列的值加上变量 a 的结果,以及第 1 列的值与变量 b 连接后的结果。

5. 用法四:awk -f {awk脚本} {文件名}

通过 -f 选项可以指定一个 awk 脚本文件,然后对指定的文件名进行处理。

实例:使用外部 awk 脚本
bash 复制代码
echo "案例 4:用法四 - 实例:使用外部 awk 脚本"
# 创建一个简单的 cal.awk 脚本
echo '{print $1, $2}' > cal.awk

awk -f cal.awk log.txt
echo "---------------------------------------------"

# 删除测试文件和临时脚本
rm -f log.txt cal.awk

代码解释

  • echo '{print $1, $2}' > cal.awk:创建一个名为 cal.awk 的脚本文件,内容为打印每行的第 1 列和第 2 列。
  • awk -f cal.awk log.txt:使用 -f 选项指定 cal.awk 脚本,对 log.txt 文件进行处理。

最后,rm -f log.txt cal.awk 用于删除创建的测试文件 log.txt 和临时脚本 cal.awk

使用方法:

  1. 将上述每个案例的代码分别保存为独立的脚本文件,例如 usage1.shusage2.sh 等。
  2. 赋予每个脚本文件执行权限:chmod +x [脚本文件名]
  3. 逐个运行脚本:./[脚本文件名]

这样可以更清晰地看到每个 awk 用法案例的具体运行过程和结果。

运算符

1. 创建测试文件

首先创建一个用于测试的文件 log.txt,并添加一些示例数据,这些数据将用于后续各种 awk 过滤操作的演示。

bash 复制代码
#!/bin/bash
# 创建测试文件 log.txt 并写入示例数据
echo "2 this is a test
3 Do you like awk
This's a test
10 There are orange,apple,mongo" > log.txt

解释 :这里使用 echo 命令将几行文本内容输出到 log.txt 文件中。这些文本行将作为测试数据,方便我们展示不同的 awk 过滤命令的效果。

2. 案例 1:过滤第一列大于 2 的行

bash 复制代码
echo "案例 1:过滤第一列大于 2 的行"
echo "命令:awk '$1>2' log.txt"
awk '$1>2' log.txt
echo ""

解释

  • awk 是一个强大的文本处理工具,用于对文本文件进行逐行处理。
  • 在这个命令中,$1 表示文件中每行按默认分隔符(空格或制表符)分割后的第一列。
  • $1>2 是一个条件表达式。awk 在读取 log.txt 文件的每一行时,会对这一行进行分析,提取出第一列的值,然后将其与数字 2 进行比较。
  • 如果第一列的值大于 2,那么这一行就满足条件,awk 会将这一行输出。因此,在我们的示例数据中,满足该条件的行 "3 Do you like awk"、"This's a test" 和 "10 There are orange,apple,mongo" 会被输出。

3. 案例 2:过滤第一列等于 2 的行

bash 复制代码
echo "案例 2:过滤第一列等于 2 的行"
echo "命令:awk '$1==2 {print $1,$3}' log.txt"
awk '$1==2 {print $1,$3}' log.txt
echo ""

解释

  • 同样,$1 代表每行的第一列。$1==2 是一个条件判断,用于检查每行的第一列的值是否等于 2。
  • {print $1,$3} 是当行满足 $1==2 这个条件时执行的操作。它表示输出满足条件的行的第一列和第三列。
  • awk 读取 log.txt 文件的每一行时,会判断该行第一列是否等于 2。对于满足条件的行,awk 会输出该行的第一列和第三列。在我们的示例数据中,只有 "2 this is a test" 这一行满足条件,所以会输出 "2 is"。

4. 案例 3:过滤第一列大于 2 并且第二列等于 'Are' 的行

bash 复制代码
echo "案例 3:过滤第一列大于 2 并且第二列等于 'Are' 的行"
echo "命令:awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt"
awk '$1>2 && $2=="Are" {print $1,$2,$3}' log.txt
echo ""

解释

  • $1>2 && $2=="Are" 是一个复合条件。其中 $1>2 检查每行的第一列是否大于 2,$2=="Are" 检查每行的第二列是否等于字符串 "Are"。只有当这两个条件同时满足时,该行才符合要求。
  • {print $1,$2,$3} 是当行满足复合条件时执行的操作,即输出满足条件的行的第一列、第二列和第三列。
  • awk 在读取 log.txt 文件的每一行时,会依次检查每行是否满足这个复合条件。在我们的示例数据中,只有 "3 Do you like awk" 这一行中,第一列 "3" 大于 2,第二列 "Do" 并不等于 "Are",不满足条件;而 "10 There are orange,apple,mongo" 同样不满足。只有 "3 Are you" 这种形式(假设原始数据存在)才会满足条件并被输出。

5. 删除测试文件

在完成所有案例的演示后,为了保持环境整洁,可以删除测试文件 log.txt

bash 复制代码
rm -f log.txt

解释rm -f log.txt 命令用于删除名为 log.txt 的文件。-f 选项表示强制删除,即使文件只读或者不存在也不会提示错误信息。

使用方法

  1. 将上述代码分别保存为不同的脚本文件(如果需要单独运行每个案例),或者保存为一个完整的脚本文件(例如 filter_awk_demo.sh)。
  2. 为脚本文件添加执行权限:chmod +x [脚本文件名]
  3. 运行脚本:如果是分开保存的脚本文件,逐个运行;如果是保存为一个完整的脚本文件,直接运行 ./filter_awk_demo.sh

这样,你可以清晰地看到每个 awk 过滤条件的具体操作和输出结果。

内建变量


内建变量使用案例

以下是基于表格中的内置变量编写的一些简单代码案例:

1. 创建测试文件

首先,创建一个简单的测试文件用于演示。假设创建一个名为 test.txt 的文件,内容如下:

bash 复制代码
#!/bin/bash

# 创建测试文件
echo "line1 word1 word2
line2 word3 word4
line3 word5 word6" > test.txt

2. 使用变量 $1(这里对应表格中的 Sn,假设 FS 为空格)

  • 案例:打印每行的第一个字段。
  • 代码
bash 复制代码
echo "案例:打印每行的第一个字段"
awk '{print $1}' test.txt
echo ""
  • 解释$1 表示每行按默认分隔符(这里假设是空格,对应表格中的 FS)分割后的第一个字段。awk 会逐行读取 test.txt 文件,并输出每行的第一个字段,即"line1"、"line2"、"line3"。

3. 使用变量 $0(对应表格中的 S0

  • 案例:打印完整的输入记录(整行)。
  • 代码
bash 复制代码
echo "案例:打印完整的输入记录"
awk '{print $0}' test.txt
echo ""
  • 解释$0 代表完整的一行。awk 会逐行读取 test.txt 文件并原样输出每行内容,即"line1 word1 word2"、"line2 word3 word4"、"line3 word5 word6"。

4. 使用变量 ARGC

  • 案例:在脚本中传递参数并获取参数数量。
  • 代码
bash 复制代码
#!/bin/bash

# 创建测试文件
echo "line1 word1 word2
line2 word3 word4
line3 word5 word6" > test.txt

# 使用 awk 并传递参数
awk -v arg1=value1 -v arg2=value2 'BEGIN{print ARGC}' test.txt
echo ""
  • 解释ARGC 表示命令行参数的数量。在这个案例中,我们通过 -v 选项给 awk 传递了两个参数(arg1arg2),再加上默认的文件名参数(test.txt),所以 ARGC 的值为 3。BEGIN 块在处理文件内容之前执行,这里用于打印 ARGC 的值。

5. 使用变量 ARGV

  • 案例:在脚本中传递参数并查看参数数组。
  • 代码
bash 复制代码
#!/bin/bash

# 创建测试文件
echo "line1 word1 word2
line2 word3 word4
line3 word5 word6" > test.txt

# 使用 awk 并传递参数
awk -v arg1=value1 -v arg2=value2 'BEGIN{for(i = 0; i < ARGC; i++) print ARGV[i]}' test.txt
echo ""
  • 解释ARGV 是包含命令行参数的数组。在这个案例中,我们通过 -v 选项传递了两个参数,再加上默认的文件名参数。BEGIN 块中的循环用于逐个打印 ARGV 数组中的元素,即程序名(通常是 awk)、arg1=value1arg2=value2test.txt

6. 使用变量 FILENAME

  • 案例:打印当前文件名。
  • 代码
bash 复制代码
echo "案例:打印当前文件名"
awk '{print FILENAME}' test.txt
echo ""
  • 解释FILENAME 表示当前文件名。awk 在处理 test.txt 文件时,会逐行输出文件名 test.txt

7. 使用变量 NR

  • 案例:打印行号。
  • 代码
bash 复制代码
echo "案例:打印行号"
awk '{print NR, $0}' test.txt
echo ""
  • 解释NR 表示已经读出的记录数,即行号(从1开始)。awk 会逐行读取 test.txt 文件,并输出每行的行号和整行内容,例如"1 line1 word1 word2"、"2 line2 word3 word4"、"3 line3 word5 word6"。

8. 使用变量 NF

  • 案例:打印每行的字段数。
  • 代码
bash 复制代码
echo "案例:打印每行的字段数"
awk '{print NF}' test.txt
echo ""
  • 解释NF 表示一条记录的字段数目。awk 会逐行读取 test.txt 文件,并输出每行的字段数,这里每行都有3个字段,所以会输出"3"、"3"、"3"。

9. 删除测试文件

在完成所有案例演示后,删除测试文件:

bash 复制代码
rm -f test.txt

使用方法

  1. 将上述每个案例的代码分别保存为独立的脚本文件(例如 case1.shcase2.sh 等)。
  2. 赋予每个脚本文件执行权限:chmod +x [脚本文件名]
  3. 逐个运行脚本:./[脚本文件名]

这样可以清晰地看到每个变量在 awk 中的应用和效果。


以下是对这些awk命令用法的优化讲解:

1. 创建测试文件

首先创建一个名为log.txt的测试文件,用于演示各种awk操作。

bash 复制代码
#!/bin/bash

# 创建测试文件log.txt并写入示例数据
echo "2 this is a test
3 Do you like awk
This's a test
10 There are orange,apple,mongo" > log.txt

2. 案例1:输出第二列包含"th",并打印第二列与第四列

bash 复制代码
echo "案例1:输出第二列包含'th',并打印第二列与第四列"
echo "命令:awk '$2 ~ /th/ {print $2,$4}' log.txt"
awk '$2 ~ /th/ {print $2,$4}' log.txt
echo ""

解释

  • awk中,$2表示每行按默认分隔符(空格或制表符)分割后的第二列。
  • ~是匹配操作符,用于检查第二列是否匹配后面的正则表达式模式。
  • /th/是正则表达式模式,表示要查找包含"th"的字符串。
  • {print $2,$4}表示当第二列匹配"th"时,打印第二列和第四列。在示例数据中,满足条件的是"this a"。

3. 案例2:输出包含"re"的行

bash 复制代码
echo "案例2:输出包含're'的行"
echo "命令:awk '/re/ ' log.txt"
awk '/re/ ' log.txt
echo ""

解释

  • 这里的/re/是一个正则表达式模式。在awk中,如果只给出正则表达式模式而没有指定操作,默认操作是打印整行。
  • 所以awk会逐行检查log.txt中的每一行,只要该行包含"re",就会输出该行。在示例数据中,符合条件的行是"3 Do you like awk"和"10 There are orange,apple,mongo"。

4. 案例3:忽略大小写

bash 复制代码
echo "案例3:忽略大小写"
echo "命令:awk 'BEGIN{IGNORECASE=1} /this/' log.txt"
awk 'BEGIN{IGNORECASE=1} /this/ ' log.txt
echo ""

解释

  • BEGIN{IGNORECASE=1}awk的特殊块和变量设置。BEGIN块在处理文件内容之前执行,IGNORECASEawk的一个变量,当设置为1时,表示在进行模式匹配时忽略大小写。
  • /this/是正则表达式模式,在忽略大小写的情况下查找包含"this"的行。在示例数据中,符合条件的行是"2 this is a test"和"This's a test"。

5. 案例4:模式取反

bash 复制代码
echo "案例4:模式取反"
echo "命令:awk '$2!~ /th/ {print $2,$4}' log.txt"
awk '$2!~ /th/ {print $2,$4}' log.txt
echo ""

解释

  • $2!~ /th/是模式取反操作。!~表示不匹配,即检查第二列是否不包含"th"。
  • {print $2,$4}表示当第二列不包含"th"时,打印第二列和第四列。在示例数据中,符合条件的结果是"Are like"、"a"和"There orange,apple,mongo"。

6. 另一种模式取反方式

bash 复制代码
echo "案例5:另一种模式取反方式"
echo "命令:awk '!/th/ {print $2,$4}' log.txt"
awk '!/th/ {print $2,$4}' log.txt
echo ""

解释

  • !/th/是对整个行进行模式取反操作。它检查整行是否不包含"th"。
  • {print $2,$4}表示当整行不包含"th"时,打印第二列和第四列。在示例数据中,结果与案例4相同。

7. 删除测试文件

在完成所有案例演示后,为了保持环境整洁,删除测试文件。

bash 复制代码
rm -f log.txt

使用方法

  1. 将上述代码保存为一个脚本文件,例如awk_regex_demo.sh
  2. 为脚本文件添加执行权限:chmod +x awk_regex_demo.sh
  3. 运行脚本:./awk_regex_demo.sh,观察每个案例的输出结果。

通过以上优化后的内容,可以更清晰地理解和掌握awk中与正则表达式和字符串匹配相关的操作。


awk脚本练习

关于 awk 脚本,我们需要注意两个关键词 BEGIN 和 END。

BEGIN{ 这里面放的是执行前的语句 }

END {这里面放的是处理完所有的行后要执行的语句 }

{这里面放的是处理每一行时要执行的语句}

假设有这么一个文件(学生成绩表):

bash 复制代码
$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

我们的 awk 脚本如下:

bash 复制代码
$ cat cal.awk
#!/bin/awk -f
#运行前
BEGIN {
    math = 0
    english = 0
    computer = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#运行中
{
    math+=$3
    english+=$4
    computer+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n", $1, $2, $3,$4,$5, $3+$4+$5
}
#运行后
END {
    printf "---------------------------------------------\n"
    printf "  TOTAL:%10d %8d %8d \n", math, english, computer
    printf "AVERAGE:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}


相关推荐
-Harvey1 小时前
ubuntu为Docker配置代理
linux·ubuntu·docker
thehunters1 小时前
win10 ubuntu 使用Android ndk 问题:clang-14: Exec format error
android·linux·ubuntu
Ven%2 小时前
如何让后台运行llamafactory-cli webui 即使关掉了ssh远程连接 也在运行
运维·人工智能·chrome·python·ssh·aigc
迷茫的小技术5 小时前
OSPF使能配置
运维·服务器·网络
soragui5 小时前
【Ubuntu】想知道怎么通过命令行查看笔记本电池健康程度吗?
linux·ubuntu·电脑
caron45 小时前
Python--正则表达式
python·正则表达式
小学导航员6 小时前
centos服务器 /1ib64/libm.so.6: version “GLIBc 2.27’ not found 异常
linux·服务器·centos
揽星逐月酒微醺6 小时前
find 查找文件grep匹配数据
linux·运维·服务器
银河麒麟操作系统6 小时前
【银河麒麟高级服务器操作系统】服务器异常重启故障分析及处理建议
linux·运维·服务器·安全·电脑
Codeking__6 小时前
Linux初识——基本指令
linux·运维·服务器