基于响应式设计的网站建设,打车软件开发,企业信息查询源码,wordpress前台注册登录弹窗代码简介
在Linux和Unix操作系统中#xff0c;文本处理是一个常见的任务。AWK命令是一个强大的文本处理工具#xff0c;专门进行文本截取和分析#xff0c;它允许你在文本文件中查找、过滤、处理和格式化数据。本文将深入介绍Linux中的AWK命令#xff0c;让你了解其基本用法和…简介
在Linux和Unix操作系统中文本处理是一个常见的任务。AWK命令是一个强大的文本处理工具专门进行文本截取和分析它允许你在文本文件中查找、过滤、处理和格式化数据。本文将深入介绍Linux中的AWK命令让你了解其基本用法和高级功能以便更高效地处理文本数据。 什么是AWK
AWK是一种处理文本文件的编程语言它得名于其创始人Alfred Aho、Peter Weinberger和Brian Kernighan的姓氏首字母。AWK在命令行中使用但更多是作为脚本来使用。AWK语言的强大之处在于它可以轻松地执行以下任务 文本搜索和匹配AWK可以在文本中搜索特定模式或关键字并执行相应的操作。 数据提取和转换它可以从文本中提取数据并将其转换成不同的格式。 报告生成AWK可以生成自定义格式的报告适用于文本文件中的数据分析。 文本编辑它可以用于编辑文本文件添加、删除或修改文本行。 AWK命令的执行过程
基本语法
awk -v varvalue 模式pattern { 动作action } filename awk的指令(pattenaction)一定要用单引号 ... 括起来动作一定要用花括号 { ... } 括起模式可以是正则表达式、条件表达式或两种组合如果模式是正则表达式要用定界符/ 动作之间用 ; 分开定义自定义变量var不需要接$符号
完整语法
awk BEGIN{commands}pattern{commands}END{commands} filename或
awk BEGIN {# 初始化操作处理数据前执行的命令。例如设置变量等
}/pattern1/ {# 当匹配到 pattern1 时执行的操作
}/pattern2/ {# 当匹配到 pattern2 时执行的操作
}END {# 输出最终结果或进行清理操作处理数据后执行的命令
} filename执行过程的详细解释
awk 命令启动并读取 filename 中的文本文件作为输入数据。如果未提供 filename则默认从标准输入读取数据。BEGIN 块中的命令会在处理输入文件之前执行一次。这通常用于初始化变量、设置选项或执行其他预处理操作。awk 逐行读取输入文件并将每一行拆分成字段默认以空格为字段分隔符可以使用 -F 选项指定其他分隔符。pattern 块中的命令会在输入行匹配指定的模式时执行。模式可以是正则表达式或其他条件。如果存在多个 pattern 块则会根据匹配的模式按顺序执行相应的命令。pattern语句块中的通用命令是最重要的部分是可选的。如果没有提供pattern语句块则默认执行END{ ... }。在 pattern 块中你可以访问字段和执行各种操作。例如可以对字段进行计算、打印匹配行或根据条件执行不同的操作。当 awk 处理完输入文件的所有行后它会执行 END 块中的命令。这通常用于输出最终结果、汇总数据或执行清理操作。awk 完成处理后它会将结果打印到标准输出通常是终端除非您在脚本中显式使用 print 命令输出结果。 基本用法
在终端中你可以使用以下的形式运行AWK命令
1. 最简单的形式
awk [选项] { action } file.txt
这是最基本的形式它会将 file.txt 文件的所有行都执行操作action。
选项参数有
-F 指定输入文件的字段分隔符用于将输入行分割为字段。示例
awk -F, { print $1 } data.txt
在这个示例中-F, 指定逗号 , 作为字段分隔符然后打印每行的第一个字段。
-v 定义一个用户定义变量可以在脚本中使用。示例
awk -v nameJohn { print Hello, name ! } file.txt
在这个示例中-v 选项定义了一个名为 name 的变量并将其值设置为 John然后在脚本中使用它。
-f 指定包含 awk 脚本的文件以便在执行时加载脚本。示例
awk -f myscript.awk file.txt
在这个示例中-f 选项指定了一个名为 myscript.awk 的脚本文件awk 将执行其中的命令。-W [option]启用某些扩展选项。示例
awk -W version
这将显示 awk 的版本信息。
awk -W help
打印全部awk选项和每个选项的简短说明。
-E切换为扩展正则表达式ERE模式匹配。示例
awk -E /[0-9]/ { print } file.txt
在这个示例中-E 选项允许使用扩展正则表达式模式匹配包含数字的行。
-i inplace在原始文件中进行原地编辑。示例
awk -i inplace { sub(old_pattern, new_pattern) } 1 file.txt
这将在 file.txt 中查找并替换第一个匹配的 old_pattern 为 new_pattern并将结果写回原始文件。
-n禁用默认的自动打印行为。示例
awk -n /pattern/ { print } file.txt
这将只打印包含 pattern 的行不会自动打印所有行。
-FPOSIX使用 POSIX 标准的字段分隔符。示例
awk -FPOSIX { print $1 } data.txt
这将使用 POSIX 标准的字段分隔符进行字段分割。
-Wlint启用 lint 模式用于检查 awk 脚本中的潜在问题。示例
awk -Wlint -f myscript.awk file.txt
这将启用 lint 模式并检查 myscript.awk 中的潜在问题。
-Wsourceprogram-text允许在命令行上直接提供 awk 脚本。示例
awk -Wsource{ print Hello, World! } file.txt
这将在命令行上直接提供 awk 脚本然后在 file.txt 上执行。
2. 指定字段分隔符的形式
awk -F, { print $1, $2 } data.csv
这个形式使用了 -F 选项来指定字段分隔符为逗号然后打印每行的第一个和第二个字段。
3. 使用脚本文件的形式
awk -f myscript.awk file.txt
在这个形式中awk 使用了 -f 选项后面跟着一个包含 awk 脚本的文件 myscript.awk并对 file.txt 文件执行该脚本中定义的操作。
4. 设置变量的形式
awk -v varvalue { print var, $1 } file.txt
这个形式使用了 -v 选项来设置一个变量 var然后将其与文件中的第一个字段一起打印。
5. 条件过滤的形式
awk pattern { action } filename
pattern是一个正则表达式或条件用于匹配文本中的行。action是在满足条件的行上执行的操作。filename是要处理的文本文件的名称。
这个形式使用了正则表达式模式 /pattern/只对文件中匹配该模式的行执行操作action。
以下是一个示例演示了如何使用AWK命令查找并打印包含关键字的行
awk /help/ { print } english.txt这将在名为english.txt的文件中查找包含关键字help的行并将它们打印到终端。 其它
有时候AWK命令的形式的部分会有省略有如下几种情况举例说明
1. 只有模式没有动作结果为显示$0$0 表示整行文本
awk /chen/ scores.txt 2. 只有动作没有模式就直接执行动作
who | awk {print $2} 字段和分隔符
内置变量$1
AWK默认使用空格作为字段分隔符。在处理文本时它将文本行分割成多个字段你可以使用$1、$2、$3等特殊的内置变量来引用这些字段$0 表示整行文本它们用于表示当前正在处理的输入行或记录的不同字段列的值。例如$1代表文本中第一个字段$2代表第二个字段$n 表示第n个字段以此类推。
以下是一个示例演示如何使用AWK命令提取文本行中的第二个字段
awk { print $2 } english.txt 如果文本文件中的字段是以逗号、制表符或其他字符分隔的你可以使用 -F 选项来指定分隔符。例如如果文本以逗号分隔您可以这样使用
awk -F, { print $2 } english.txt 内置变量FS OFS AWK 命令中用于控制字段的输入和输出分隔符的内置变量
输入分隔符 FS Field Separator用于指定字段的输入分隔符。默认情况下awk 使用空格作为字段分隔符但你可以使用 -F 选项或在 BEGIN 块中设置 FS 来指定不同的字段分隔符。输出分隔符 OFS Output Field Separator用于指定字段的输出分隔符。默认情况下OFS 为空格这意味着 awk 在打印输出时会在字段之间插入空格。你可以在 BEGIN 块中设置 OFS 来指定不同的输出字段分隔符。
示例 1
以下是一个示例演示了如何在 awk 中使用 FS 和 OFS 来控制字段分隔和输出分隔
假设有一个 CSV 文件 data.csv 包含以下内容
Alice,90,88,92
Bob,78,85,80
Charlie,92,94,89
可以使用以下 awk 命令来读取该文件将逗号作为字段分隔符并在输出中使用制表符作为字段分隔符
awk BEGIN {FS ,OFS \t # 使用制表符作为输出字段分隔符
}
{print $1, $2, $3, $4
} data.csv 命令也可以这样写入注意在 AWK 中可以在同一行上包含多个命令并使用分号来分隔它们
awk BEGIN { FS ,; OFS \t } { print $1, $2, $3, $4 } data.csv运行此命令将输出以下内容 在这个示例中BEGIN 块中设置了 FS 为逗号表示字段分隔符是逗号。然后OFS 被设置为制表符表示输出字段分隔符是制表符。这样在输出时字段之间将使用制表符分隔。
示例 2 OFS 设置为逗号输出重定向到csv文件
awk -F: OFS,{print $1,$3,$5} /etc/passwd passwd.csv
运行此命令将输出以下内容 补充
在AWK中使用-F选项来指定字段分隔符可以使用单引号、双引号或不使用引号它们的效果是相同的。这是因为在命令行中单引号或双引号通常用于防止特殊字符的解释或空格的分隔。 内置变量
AWK还提供了一些内置变量用于执行更复杂的操作
NR代表记录数行号用于跟踪处理的行数。
awk NR 3 NR 5{print NR,$0} /etc/passwd
# 或写成下面这种形式作用结果相同。因为在 AWK 中逗号“ , ”用于表示一个范围其中 NR3,NR5 表示从行号 3 到行号 5 的范围。
awk NR3,NR5{print NR,$0} /etc/passwd
解释这个命令会打印第三到第五行的行号和内容。使用 NR行号内置变量来检查每一行的行号。NR 3 表示行号大于等于3NR 5 表示行号小于等于5。
NF代表字段数用于确定每行有多少个字段。
awk { print NF, $0 } filename.txt
解释上述命令将打印每行的字段数和内容。
FS代表字段分隔符用于指定字段之间的分隔符默认是任何空格。
awk BEGIN { FS , } { print $2 } english.txt
解释上面的示例使用BEGIN块来在AWK脚本开始执行之前设置FS变量为逗号。然后打印每行的第二个字段AWK会使用FS来解释输入数据中的字段分隔符。
RS代表记录分隔符用于指定记录之间的分隔符。记录分隔符是一个用于分隔文本中记录行的特殊字符或字符串。默认情况下RS的值是一个换行符\n这意味着每行文本都被视为一个记录。可以通过设置RS来更改记录分隔符以根据需要处理多行记录例如RS \n\n表示两个连续的换行符分隔记录。
awk BEGIN { RS \n\n } { print NR, $0 } filename.txt
解释上述命令将以双换行符作为记录分隔符并打印每个记录的行号和内容。
补充记录分隔符RS用于分隔不同的记录行字段分隔符FS用于分隔记录内的不同字段。通过设置这两个变量你可以适应不同的文本数据格式和处理要求。
$n : 当前记录的第n个字段比如n为1表示第一个字段n为2表示第二个字段。
awk { if (NF 16) print NR, $1, $NF } english.txt
这将打印出那些包含16个或更多字段的行的行号NR、第一个字段$1和最后一个字段$NF。
$0 : 这个变量包含执行过程中当前行的文本内容。
awk /pattern/ { print $0 } filename.txt
解释上述命令将打印包含特定模式pattern的整行内容。
ARGC : 命令行参数的数目。
awk BEGIN{ print ARGC } sshd.txt data.csv 解释上述命令将打印命令行参数的数目包括文件名。
ARGIND : 命令行中当前文件的位置从0开始算。
awk { print ARGIND, FILENAME } file1.txt file2.txt
解释上述命令将打印当前处理的文件位置和文件名。
ARGV : 包含命令行参数的数组。
awk BEGIN { for (i in ARGV) print ARGV[i] } file1.txt file2.txt
解释上述命令将打印命令行参数数组中的所有参数。
CONVFMT : 数字转换格式默认值为%.6g。
awk BEGIN { CONVFMT %.2f; print 1.234567 }
解释上述命令将设置数字输出格式为两位小数并打印。
ENVIRON : 环境变量关联数组。
awk BEGIN { print ENVIRON[HOME] }
解释上述命令将打印用户的家目录。
ERRNO : 最后一个系统错误的描述。
awk BEGIN { if (system(nonexistent_command)) print Error:, ERRNO }
解释上述命令将尝试执行一个不存在的命令并打印系统错误描述。
FIELDWIDTHS : 字段宽度列表用空格键分隔。
awk BEGIN { FIELDWIDTHS 3 5 2; print $1, $2, $3 } filename.txt
解释上述命令将按指定的字段宽度解析输入文本。
FILENAME : 当前输入文件的名。
awk { print FILENAME } file1.txt file2.txt
解释上述命令将打印当前处理的文件名。
FNR : 同NR :但相对于当前文件。
awk { print FNR, $0 } file1.txt file2.txt
解释上述命令将打印相对于当前文件的行号和内容。
IGNORECASE : 如果为真则进行忽略大小写的匹配。
awk BEGIN { IGNORECASE 1 } /pattern/ { print $0 } filename.txt
解释上述命令将进行大小写不敏感的模式匹配。
OFMT : 数字的输出格式默认值是%.6g。
awk BEGIN { OFMT %.3f; print 1.234567 }
解释上述命令将设置数字输出格式为三位小数并打印。
OFS : 输出字段分隔符默认值是一个空格。
awk BEGIN { FS ,; OFS \t } { print $1, $2, $3, $4 } data.csv解释在这个示例中BEGIN 块中设置了 FS 为逗号表示字段分隔符是逗号。然后OFS 被设置为制表符表示输出字段分隔符是制表符。这样在输出时字段之间将使用制表符分隔。
ORS : 输出记录分隔符默认值是一个换行符。
awk BEGIN { ORS \n\n } { print $0 } filename.txt
解释上述命令将以双换行符作为输出记录分隔符。
RSTART : 由match函数所匹配的字符串的第一个位置。
echo Hello, World | awk match($0, /World/) { print RSTART }
解释上述命令使用match函数在输入文本中查找字符串World并打印匹配的起始位置RSTART变量将包含匹配字符串的第一个字符在输入文本中的位置。
RLENGTH : 由match函数所匹配的字符串的长度。
echo Hello, World | awk match($0, /World/) { print RLENGTH }
解释上述命令使用match函数在输入文本中查找字符串World并打印匹配的长度RLENGTH变量将包含匹配字符串的长度。
SUBSEP : 数组下标分隔符默认值是34。
awk BEGIN { print SUBSEP }
解释上述命令在AWK的BEGIN块中打印SUBSEP的值默认情况下SUBSEP的值是ASCII码值为34的字符双引号它用于分隔多维数组中的索引以便创建关联数组的复杂结构。 AWK 操作符
AWK 是一种强大的文本处理工具支持各种操作符用于执行条件检查、数学运算、字符串处理和模式匹配等操作。以下是一些常见的 AWK 操作符及其示例
算术操作符
加法操作。-减法操作。*乘法操作。/除法操作。%取模操作。
示例这个命令计算每行中的第一个字段和第二个字段的和并将结果打印出来。
awk { result $1 $2; print result } data.txt
关系操作符
相等。!不相等。小于。大于。小于等于。大于等于。
示例这个命令检查第三个字段是否等于 1001如果是则打印相应行的第一个字段。
awk $3 1001 { print $1 } data.txt
逻辑操作符
逻辑与。||逻辑或。!逻辑非。
示例这个命令检查第二个字段是否大于 50 并且第三个字段是否小于 90如果满足条件则打印相应行的第一个字段。
awk $2 50 $3 90 { print $1 } data.txt
赋值操作符
赋值操作。
示例这个命令计算每行中的第一个字段和第二个字段的和并将结果赋值给变量 total然后打印出总和。
awk { total $1 $2; print Total: total } data.txt
增量/减量操作符
增量操作。--减量操作。
示例这个命令用于计算文件中的总行数。每次处理一行时会将变量 count 增加 1。在处理结束时END 部分打印总行数。
awk { count; } END { print Total Lines: count } data.txt
模式匹配操作符
~匹配模式。!~不匹配模式。
示例这个命令匹配第四个字段是否包含特定模式在示例中是 pattern。如果匹配成功则打印相应行的第一个字段。
awk $4 ~ /pattern/ { print $1 } data.txt
字符串连接操作符
用于连接字符串。
示例这个命令将每行的第一个字段 $1和第二个字段 $2连接起来形成完整的姓名并打印出来。
awk { fullName $1 $2; print Full Name: fullName } data.txt
三元条件操作符
? :用于条件赋值。
示例这个命令根据第三个字段的值是否大于等于 90 来确定考试状态。如果条件成立将 Pass 赋给变量 status否则赋给 Fail然后打印学生的姓名和状态。
awk { status ($3 90) ? Pass : Fail; print $1, status } data.txt 正则表达式
正则表达式Regular Expression简称 Regex 或 Regexp是一种强大的文本模式匹配工具用于在文本中查找、匹配和操作符合特定模式的字符串。正则表达式由普通字符和特殊字符组成它们可以形成复杂的匹配规则。正则表达式在 awk 命令中广泛应用用于处理文本数据。
在某些编程语言和工具中正则表达式通常是用两个斜杠 / 括起来的例如 JavaScript 和 Perl。这种斜杠括起来的格式用于表示正则表达式的开始和结束
下面介绍正则表达式中的常见字符并提供在 awk 中的示例和解释
普通字符
普通字母和数字
正则表达式中的普通字母和数字通常表示它们自身。例如字母 a 匹配字符 a。
awk /apple/ {print} file.txt
这个命令将打印包含匹配 apple 的文本行。
空格和标点符号
空格和大多数标点符号通常表示它们自身。例如空格字符 匹配空格。
awk /hello, world/ {print} file.txt
这个命令将打印包含 hello, world 的文本行。
特殊字符
.点号匹配任何单个字符除了换行符 \n
awk /a.b/ {print} file.txt
这个命令将打印包含 a.b 模式的所有文本行其中 . 匹配任意字符。
*星号匹配前一个元素零次或多次。
awk /ab*c/ {print} file.txt
这个命令将打印包含 abc、abbc、abbbc 等模式的文本行星号 * 表示匹配 b 零次或多次。
加号匹配前一个元素一次或多次。
awk /abc/ {print} file.txt
这个命令将打印包含 abc、abbc、abbbc 等模式的文本行加号 表示匹配 b 一次或多次。
?问号匹配前一个元素零次或一次。
awk /ab?c/ {print} file.txt
这个命令将打印包含 ac、abc 模式的文本行问号 ? 表示匹配 b 零次或一次。
[ ]字符类匹配括号内的任意一个字符。
awk /[aeiou]/ {print} file.txt
这个命令将打印包含任何元音字母的文本行。
[^]否定字符类匹配不在括号内的任意一个字符。
awk /[^0-9]/ {print} file.txt
这个命令将打印包含任何非数字字符的文本行。
{ } 用于控制匹配模式的重复次数。
awk /[0-9]{2,4}/ {print} file.txt这个命令将匹配包含到个连续数字字符的文本行并打印它们。
( )分组用于创建子表达式允许对子表达式应用量词。当使用 () 分组时它们允许你将多个元素视为一个整体并对该整体应用量词或其他正则表达式操作符。
awk /(abc)/ {print} file.txt
这个命令将打印包含 abc、abcabc、abcabcabc 等重复模式的文本行。其他示例
1. 匹配电话号码使用 () 分组来匹配电话号码的不同格式。
awk /(\d{3}-)?\d{3}-\d{4}/ {print} file.txt
这个示例中正则表达式 (\d{3}-)?\d{3}-\d{4} 匹配形如 123-456-7890 或 456-7890 的电话号码。括号内的 (\d{3}-)? 表示可选的区号。
2. 匹配HTML标签使用 () 分组来匹配HTML标签。
awk /(\w).\/\1/ {print} file.html
此示例中正则表达式 (\w).\/\1 可以匹配类似于 p这是段落/p 的HTML标签其中 (\w) 匹配标签名并使用 \1 来引用匹配的标签名确保起始和结束标签相匹配。
3. 匹配IPv4地址使用 () 分组来匹配IPv4地址。
awk /((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)/ {print} file.txt
这个正则表达式 ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?) 用于匹配IPv4地址括号内的部分 (25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\. 匹配一个IP地址的一部分。
|分支用于分支匹配匹配 | 左边或右边的表达式。
awk /apple|banana/ {print} file.txt
这个命令将打印包含 apple 或 banana 的文本行。
^脱字符匹配文本的开头。
awk /^start/ {print} file.txt
这个命令将打印以 start 开头的文本行。
$美元符号匹配文本的结尾。
awk /end$/ {print} file.txt
这个命令将打印以 end 结尾的文本行。
\反斜杠用于转义特殊字符。
awk /\./ {print} file.txt
这个命令将打印包含句号 . 的文本行反斜杠 \ 用于转义特殊字符。
\d匹配数字字符等同于 [0-9]。
awk /[0-9]/ {print} file.txt
这个命令将打印包含数字字符的文本行。
注意 在标准的 awk 中\d、\D 和 \w 也不是合法的正则表达式转义序列因此不能直接在 awk 中使用。这些转义序列通常用于其他支持 Perl 兼容正则表达式语法的工具和编程语言而不是标准的 awk。因为 \d 不是 awk 的标准正则表达式语法所以在标准的awk 中将不会正常工作。应该使用 [0-9] 来匹配数字字符。
\D匹配非数字字符等同于 [^0-9]。
awk /[^0-9]/ {print} file.txt
这个命令将打印包含非数字字符的文本行。
\w匹配字母、数字和下划线字符等同于 [A-Za-z0-9_]。
awk /[A-Za-z0-9_]/ {print} file.txt
这个命令将打印包含字母、数字或下划线字符的文本行。
[A-Za-z0-9_] 是一个字符类character class用于匹配一组字符。这个字符类包含了大写字母 A 到 Z、小写字母 a 到 z、数字 0 到 9以及下划线字符 _。每个字符类中的字符都表示自身即它们匹配它们自己。即
[A-Za-z]这部分表示匹配任何一个字母无论是大写还是小写字母。[0-9]这部分表示匹配任何一个数字。_这部分表示匹配下划线字符。 \W匹配非字母、非数字和非下划线字符等同于 [^A-Za-z0-9_]。
awk /[^A-Za-z0-9_]/ {print} file.txt
这个命令将打印包含非字母、非数字或非下划线字符的文本行。
\s匹配空白字符包括空格、制表符、换行符等。
awk /[ \t]/ {print} file.txt
这个命令将打印包含空格或制表符等空白字符的文本行。
\S匹配非空白字符。
awk /\S/ {print} file.txt
这个命令将打印包含非空白字符的文本行。
\ 和 \ 用于单词边界的匹配。\ 匹配单词的开头位置\ 匹配单词的结尾位置
awk /\apple/ {print} file.txt
这个命令用 \ 来匹配以 apple 开头的单词。当 awk 扫描文本文件 file.txt 时它会打印包含以 apple 开头的单词的文本行。
awk /orange\/ {print} file.txt
这个命令用用 \ 来匹配以 orange 结尾的单词。如果文件中有 I like orange那么这个命令会匹配并打印这个文本行因为它包含以 orange 结尾的单词。
不同特殊字符的结合使用
正则表达式中的特殊字符可以结合一起使用以创建更复杂的匹配模式。以下是一些常见的示例演示了如何结合使用不同的特殊字符
结合字符类和量词你可以将字符类和量词组合在一起以匹配多个特定类型的字符。
[A-Za-z]匹配一个或多个字母字符。
awk /[A-Za-z]/ {print} file.txt
这个命令将匹配包含一个或多个字母字符的文本行诸如 abc、Hello、RegularExpressions 等包含一个或多个英文字母的文本。并打印它们。
[0-9]{2,4}匹配两到四个数字字符。
awk /[0-9]{2,4}/ {print} file.txt 也可以用这种形式awk /[012345689]{2,4}/ {print} file.txt
这个命令将匹配包含到个连续数字字符的文本行并打印它们。
结合分组和分支你可以使用分组和分支来匹配多个模式中的一个。
(apple|banana)匹配 apple 或 banana。
awk /(apple|banana)/ {print} file.txt
这个命令将匹配包含 apple 或 banana 的文本行并打印它们。
(red|blue|green) apple匹配 red apple、blue apple 或 green apple。
awk /(red|blue|green) apple/ {print} file.txt 这个命令将匹配包含 red apple、blue apple 或 green apple 的文本行并打印它们。
结合锚点和字符类结合锚点和字符类可以精确定位匹配位置。
^[\d]{3}-[\d]{2}-[\d]{4}$匹配形如 123-45-6789 的美国社会安全号码。
awk /^[0-9]{3}-[0-9]{2}-[0-9]{4}$/ {print} file.txt这个命令将匹配形如 123-45-6789 的美国社会安全号码确保整个文本行都匹配该模式。
结合转义字符和特殊字符转义字符用于匹配特殊字符本身。
\.匹配句号 .。
awk /\./ {print} file.txt
这个命令将匹配包含句号 . 的文本行并打印它们。句号在正则表达式中是一个特殊字符所以它需要通过反斜杠进行转义。
\*匹配星号 *。
awk /\*/ {print} file.txt 这个命令将匹配包含星号 * 的文本行并打印它们。星号在正则表达式中通常用于表示零个或多个重复所以它需要通过反斜杠进行转义。
结合量词和分组结合量词和分组可以匹配特定数量的重复模式。
(ab)匹配一个或多个 ab 的连续出现。
awk /(ab)/ {print} file.txt
这个命令将匹配包含一个或多个连续出现的 ab 的文本行并打印它们。
(xyz){3}匹配连续出现的 xyz 三次。 awk /(xyz){3}/ {print} file.txt
这个命令将匹配包含连续出现的 xyz 三次的文本行并打印它们。
这些示例演示了如何结合使用正则表达式中的特殊字符和操作符以创建更复杂的匹配模式以满足不同的匹配需求。正则表达式的强大之处在于它允许您构建非常灵活的模式来匹配各种文本数据。 其他应用
AWK不仅支持基本的文本处理还可以进行其他的一些数据操作如计算、条件语句、循环等。以下是一些应用的示例
awk命令的引用shell变量
在 AWK 命令中引用 shell 变量可以通过 -v 选项来实现。这允许您将 shell 变量传递给 AWK 脚本并在脚本内部使用。
下面是一个示例演示了如何引用 shell 变量
# 在 shell 中定义一个变量
nameJohn # 使用 AWK 命令引用 shell 变量
awk -v new_name$name { print new_name } file.txt
在这个示例中首先在 shell 中定义了一个名为 name 的变量并将其值设置为 John。然后通过 -v 选项将 shell 变量 name 传递给了 AWK 脚本 ($ 符号用于引用 shell 变量获取变量的值)并将其存储在 AWK 变量 name 中。在 AWK 脚本内部我们使用 new_name 变量来引用 shell 变量的值然后在 AWK 脚本内部使用 new_name 变量来打印相应行的值。
这样您可以将 shell 变量的值传递给 AWK 脚本以在 AWK 脚本中使用它们实现更灵活的文本处理和数据操作。
补充
需注意区分以下两个命令的区别
awk -v nameJohn { print name } file.txt
和
nameJohn # 定义shell变量name
awk -v new_name$name {print new_name} file.txt
这两个命令中主要区别在于nameJohn和new_name$name这两行的定义和传递方式。
第一个命令在AWK命令行中直接定义了一个AWK变量name并将其值设置为John。然后在AWK脚本内部直接使用name变量不需要双引号。
第二个命令首先在shell中定义了一个shell变量name并将其值设置为John。然后使用-v选项将shell变量name的值传递给了AWK脚本并将其存储在AWK变量new_name中。
关于双引号的问题
new_name$name 中的双引号用于将shell变量$name的值传递给new_name以确保如果name包含空格或特殊字符时值仍然保持完整。在AWK脚本内如果直接使用name而不是$name如果name包含空格或特殊字符可能会导致意外的结果。所以使用双引号是一种良好的做法以确保变量值的完整性。 条件语句
awk { if ($2 50) print $1, Pass; else print $1, Fail } scores.txt
这将根据第二个字段的值决定学生是否通过。
scores.txt文件内容 循环
awk { for (i1; iNF; i) print $i } english.txt
这将遍历每一行的字段并打印它们。 实战一个面试题
题目监控 SSH 登录失败并在 /etc/hosts.deny 中添加被封禁 IP 地址
检查/var/log/secure日志文件如果有主机用root用户连接服务器的ssh服务失败次数超过了10次就将这个IP地址写入到/etc/hosts.deny文件拒绝其访问如果这个IP已经存在就无需重复添加到/etc/hosts.deny文件。
解释
脚本首先使用 awk 命令从 /var/log/secure 中提取包含 Failed 的行并将其第11个字段通常是 IP 地址提取出来然后使用 sort 和 uniq -c 统计每个 IP 地址出现的次数最后将结果写入 sshd.txt 文件中。接下来从 sshd.txt 文件中分离 IP 地址和相应的登录失败次数并将它们存储在数组 ip_addr 和 ip_num 中。然后遍历每个 IP 地址检查它是否已经存在于 /etc/hosts.deny 文件中。如果存在则输出该信息如果不存在且登录失败次数超过10次则将该 IP 地址添加到 /etc/hosts.deny 中。最后脚本进入一个无限循环每5秒钟检查一次 /var/log/secure 中的登录失败日志如果某个 IP 地址登录失败次数超过10次则将其添加到 /etc/hosts.deny 中。
解答
具体实现以下脚本文件的内容
#!/bin/bash
# 上面一行指定了要使用的解释器为 Bash。# 提取/var/log/secure中包含Failed的行并统计IP地址出现次数保存到sshd.txt
# sort命令将 awk 输出的数据进行排序以便相同的 IP 地址会被聚合在一起
# uniq -c命令用于去除连续重复的行并在行首显示出现的数目。
awk $0 ~ /Failed/ {print $11} /var/log/secure | sort | uniq -c | awk {print $1, $2} sshd.txt# 从sshd.txt中分离IP地址和登录失败次数存储到数组
# $(...)是命令替换的语法。它将执行命令并将其输出作为字符串返回作为数组ip_addr的元素
ip_addr($(awk {print $2} sshd.txt))
ip_num($(awk {print $1} sshd.txt))# 遍历IP地址和登录失败次数
for i in ${!ip_addr[]}; doip${ip_addr[i]} num${ip_num[i]}# 检查是否已经存在于/etc/hosts.deny中# egrep 命令用来在 /etc/hosts.deny 文件中查找是否已经存在指定的 IP 地址 ${ip}# /dev/null 是Linux/Unix系统中用于重定向命令输出的一种常见方式。将命令的输出和错误都重定向到 /dev/null。# /dev/null 是一个特殊的设备文件它被用作黑洞。任何写入 /dev/null 的内容都会被丢弃而且不会显示在终端上。这常常用于丢弃不需要的输出。if egrep ${ip} /etc/hosts.deny /dev/null; thenecho ${ip} already exists in /etc/hosts.denyelseecho ################################# 如果登录失败次数大于10则添加到/etc/hosts.deny中if (($num 10)); thenecho sshd:${ip} /etc/hosts.denyecho Added ${ip} to /etc/hosts.denyfiecho ${ip} have access ${num} timesfi
done# 无限循环每5秒检查/var/log/secure中的登录失败日志
# egrep ^Failed过滤出登录状态为 Failed 的行
# sort对结果进行排序以便相同的 IP 地址被聚合在一起
# uniq -c使用 uniq 命令计数每个唯一 IP 地址出现的次数
while true; doIP_list($(awk {print $6,$11} /var/log/secure | egrep ^Failed | sort | uniq -c | awk {if($1 10) print $3}))# 遍历新的登录失败IP地址for ip in ${IP_list[]}; do# 检查是否已经存在于/etc/hosts.deny中if egrep ${ip} /etc/hosts.deny /dev/null; then: # 什么都不做else# 否则将IP地址添加到/etc/hosts.deny中echo sshd:${ip}:deny /etc/hosts.denyecho Added ${ip} to /etc/hosts.denyfidone# 在每次循环结束后脚本会等待 5 秒钟然后再次开始检查日志文件sleep 5
done总结
AWK命令是Linux中一个功能强大的文本处理工具它可以处理文本文件的各种任务包括搜索、提取、转换和报告生成。通过了解基本用法、字段和分隔符、内置变量以及高级功能您可以更高效地处理文本数据。无论您是在日常系统管理中还是在数据分析中AWK都是一个有用的工具值得掌握。希望本文能够帮助您更深入地了解AWK命令并提高您的文本处理技能。