diff --git "a/25 \351\227\253\351\233\252\350\216\262/20240603 awk\345\221\275\344\273\244.md" "b/25 \351\227\253\351\233\252\350\216\262/20240603 awk\345\221\275\344\273\244.md" new file mode 100644 index 0000000000000000000000000000000000000000..ddfb59bed7fdd7af8dc0cdc9f02683f4702e2c91 --- /dev/null +++ "b/25 \351\227\253\351\233\252\350\216\262/20240603 awk\345\221\275\344\273\244.md" @@ -0,0 +1,171 @@ +## 笔记 + +## Awk 命令的结构 + +### 1.`awk` 命令的**基本结构**如下: + +```sh +awk [选项] '脚本' 文件 +# 最简单的一个脚本,打印全文 +awk '{ print }' student_scores.csv +``` + +AWK 脚本由一个或多个语句块组成,每个语句块可以是以下三种之一: + +1. 开始语句块:在程序开始时执行 `BEGIN { print "start" }` +2. 通用语句块:逐行处理文件内容 `pattern { commands }`, +3. 结束语句块:在程序结束时执行 `END { print "end" }` + +示例: +```sh +awk 'BEGIN { print "开始" } pattern { commands } END { print "结束" }' file +# 头尾各加一行 +awk 'BEGIN { print "我是开头"} { print } END { print "我是结尾" } ' student_scores.csv +``` + +可以通过管道获取数据: +```sh +cat file | awk 'BEGIN { print "start" } pattern { commands } END { print "end" }' +``` + +### 2 语句块的构成部分 + +语句块语法:由模式 (pattern) 和动作 (action) 构成。 + +```bash +awk 'pattern { actions }' # 即 模式 {动作} +# 模式 (pattern): 可以是正则表达式、关系表达式、特定条件等。 +# 动作 (action): 一组语句,描述在匹配模式的行上执行的操作 +# 示例 +awk '/王/ { print $0 }' student_scores.csv +# 打印文件中所有包含 王 的行。 + + +awk -F, 'BEGIN { print "----开始-----" } +$2>=80 { print } +END { print "----结束-----" } +' student_scores.csv +# 脚本解释 +# -F,:指定逗号作为字段分隔符,不指定默认是空格(\t)做分隔符 +# BEGIN { print "----开始-----" }:在处理文件开始时打印“----开始-----”。 +# $2 >= 80 { print }:对于每一行,如果第二个字段(数学成绩)大于或等于80,则打印该行。 +# END { print "----结束-----" }:在处理文件结束时打印“----结束-----”。 +``` + +- 如果没有指定模式,则对每一行都执行动作。 +- 指定模式后,只有匹配模式的行,才执行动作,即满足条件才执行 + +### 3. 术语解释 + +#### Awk 中的常用选项(限命令行) + +- `-F`:指定输入字段分隔符。例如,`-F,` 将逗号设置为字段分隔符。 + - 默认是以空格\t等为分隔符 + - 类似于FS="分隔符" 在文件中使用 + +- `-v`:赋值外部变量。例如,`-v var=value`。 min=60 +- `-f`:指定 Awk 脚本文件。例如,`-f script.awk`。 +- `-W`:控制警告和其他运行时选项。例如,`-W version` 用于显示版本信息。 + +#### Awk 中的常用模式(pattern) + +- 匹配正则表达式 + - `/pattern/`:匹配包含指定模式的行。例如,`/error/` 匹配所有包含“error”的行。 + - $2 ~ /pattern/ :匹配第2列包含关键字pattern的行, + - $2 !~ /pattern/:匹配第2列不包含关键字pattern的行 + +- 比较运算符 + - 匹配第 n 行。例如,`NR == 1` 匹配第一行。 + - `==`(等于),例$2 == "张三" 匹配第二列等于张三的行 + - `!=`(不等于) + - `<`(小于) + - `<=`(小于等于) + - `>`(大于) + - `>=`(大于等于) + +- 逻辑运算符 + - `NR >= m && NR <= n`:匹配第 m 到第 n 行。例如,`NR >= 2 && NR <= 4` 匹配第2到第4行。 + - `&&`:逻辑与(AND) + - `||`:逻辑或(OR) + - `!`:逻辑非(NOT) + +- 三元运算符 + - 条件运算符 `? :` + - grade = ($2 >= 60 ? "及格" : "不及格") + + +#### Awk 中的特殊变量 + +- `NR`:表示记录的数量(当前行号)。Numbers of Rows +- `NF`:表示当前行的字段数量。`$NF`表示什么?最后一列 Number of flied +- `$0`:包含当前行的文本内容,即一整行内容。有时候也省略 +- `$1`、`$2`:表示当前行的第1个、第2个字段的内容,以次类推。 +- `FS`:输入时的域分割符。效果同-F选项 File split +- `OFS`:输出时的域分割符。out File split + +## 作业: + +1. 只显示/etc/passwd的账户 + + ``` + user@hecs-196642:~$ awk -F: '{print $1}' /etc/passwd + ``` + + + +2. 只显示/etc/passwd的账户和对应的shell,并在第一行上添加列名用户制表符shell,最后一行添加---------------- + + ``` + user@hecs-196642:~$ awk -F: 'BEGIN{print "账户\t shell"} {print $1,$NF} END{print"------------"}' /etc/passwd + ``` + + + +3. 搜索/etc/passwd有关键字root的所有行 + + ``` + user@hecs-196642:~$ awk '/root/{print $0}' /etc/passwd + ``` + + + +4. 统计/etc/passwd文件中,每行的行号,每列的列数,对应的完整行内容以制表符分隔 + + ``` + user@hecs-196642:~$ awk '{FS="\t"; print NR,NF,$0}' /etc/passwd + ``` + + + +5. 输出/etc/passwd文件中以nologin结尾的行 + + ``` + user@hecs-196642:~$ awk '/nologin/{print}' /etc/passwd + ``` + + + +6. 输出/etc/passwd文件中uid字段小于100的行 + + ``` + user@hecs-196642:~$ awk -F : '$3<100{print $0}' /etc/passwd + ``` + + + +7. /etc/passwd文件中gid字段大于200的,输出该行第一、第四字段,第一,第四字段并以制表符分隔 + + ``` + user@hecs-196642:~$ awk -F : '$4>200{print $1,$4;OFS="\t"}' /etc/passwd + ``` + + + +8. 输出/etc/passwd文件中uid字段大于等于100的行 + + ``` + user@hecs-196642:~$ awk -F : '$3>100{print $0}' /etc/passwd + ``` + + +