From 9aaa986d71d8b66127ce0aa74c9b3674c454e25f Mon Sep 17 00:00:00 2001 From: jaywcjlove Date: Sun, 30 Oct 2022 16:10:59 +0000 Subject: [PATCH] feat: add `awk.md` cheatsheet. 909527deec1ed9b19080e912db48af9d0006b293 --- docs/awk.html | 989 ++++++++++++++++++++++++++++++++++++++++++++++++++ index.html | 9 +- 2 files changed, 995 insertions(+), 3 deletions(-) create mode 100644 docs/awk.html diff --git a/docs/awk.html b/docs/awk.html new file mode 100644 index 00000000..a77873d5 --- /dev/null +++ b/docs/awk.html @@ -0,0 +1,989 @@ + + + + +Awk 备忘清单 + & awk cheatsheet & Quick Reference + + + + + + +

+ +Awk 备忘清单

+

这是 GNU awk 的单页快速参考备忘单,其中涵盖了常用的 awk 表达式和命令。

+

入门

+

试试

+
$ awk -F: '{print $1, $NF}' /etc/passwd
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
---
-F:冒号作为分隔符
{...}awk 程序
print打印当前记录
$1第一个字段
$NF最后一个字段
/etc/passwd输入数据文件
+

Awk program

+
BEGIN          {<初始化>} 
+   <pattern 1> {<计划动作>} 
+   <pattern 2> {<计划动作>} 
+   ...
+END            {< 最后的动作 >}
+
+

示例

+
awk '
+    BEGIN { print "\n>>>Start" }
+    !/(login|shutdown)/ { print NR, $0 }
+    END { print "<<<END\n" }
+' /etc/passwd
+
+

变量

+ +
          $1      $2/$(NF-1)    $3/$NF
+           ▼          ▼           ▼ 
+        ┌──────┬──────────────┬───────┐
+$0/NR ▶ │  ID  │  WEBSITE     │  URI  │
+        ├──────┼──────────────┼───────┤
+$0/NR ▶ │  1   │  baidu.com   │  awk  │
+        ├──────┼──────────────┼───────┤
+$0/NR ▶ │  2   │  google.com  │  25   │
+        └──────┴──────────────┴───────┘
+
+
+
# 第一个和最后一个字段
+awk -F: '{print $1,$NF}' /etc/passwd
+# 带行号
+awk -F: '{print NR, $0}' /etc/passwd
+# 倒数第二个字段
+awk -F: '{print $(NF-1)}' /etc/passwd
+# 自定义字符串
+awk -F: '{print $1 "=" $6}' /etc/passwd
+
+

查看: Awk 变量

+

awk 程序示例

+ +
awk 'BEGIN {print "hello world"}'        # 打印 "hello world"
+awk -F: '{print $1}' /etc/passwd         # -F: 指定字段分隔符
+# /pattern/ 仅对匹配的模式执行操作
+awk -F: '/root/ {print $1}' /etc/passwd                     
+# BEGIN 块在开始时执行一次
+awk -F: 'BEGIN { print "uid"} { print $1 }' /etc/passwd     
+# END 块在最后执行一次
+awk -F: '{print $1} END { print "-done-"}' /etc/passwd
+
+

条件

+
awk -F: '$3>30 {print $1}' /etc/passwd
+
+

查看: Conditions 条件

+

生成 1000 个空格

+
awk 'BEGIN{
+    while (a++ < 1000)
+        s=s " ";
+    print s
+}'
+
+

查看: Loops

+

数组 Arrays

+
awk 'BEGIN {
+   fruits["mango"] = "yellow";
+   fruits["orange"] = "orange"
+   for(fruit in fruits) {
+     print "The color of " fruit " is " fruits[fruit]
+   }
+}'
+
+

查看: Awk 数组

+

函数 Functions

+
# => 5
+awk 'BEGIN{print length("hello")}'
+# => HELLO
+awk 'BEGIN{print toupper("hello")}'
+# => hel
+awk 'BEGIN{print substr("hello", 1, 3)}'
+
+

查看: Functions

+

Awk 变量

+

内置变量

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
$0全线
$1, $2...$NF第一个,第二个……最后一个字段
NR记录总数(Number of Records)
NFN个字段(Nnumber of Fields)
OFSOutput Field Separator
输出字段分隔符 (default " ")
FSinput Field Separator
输入字段分隔符 (default " ")
ORSOutput Record Separator
输出记录分隔符 (default "\n")
RSinput Record Separator
输入记录分隔符 (default "\n")
FILENAME文件名
+

表达式

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
$1 == "root"第一个字段等于根
{print $(NF-1)}倒数第二个字段
NR!=1{print $0}从第 2 条记录开始
NR > 3从第 4 条记录开始
NR == 1第一次记录
END{print NR}总记录
BEGIN{print OFMT}输出格式
{print NR, $0}行号
{print NR " " $0}行号(选项卡)
{$1 = NR; print}用行号替换第一个字段
$NF > 4最后一个字段 > 4
NR % 2 == 0甚至记录
NR==10, NR==20记录 10 到 20
BEGIN{print ARGC}arguments
ORS=NR%5?",":"\n"连接记录
+

示例

+

打印总和和平均值

+
awk -F: '{sum += $3}
+     END { print sum, sum/NR }
+' /etc/passwd
+
+

打印参数

+
awk 'BEGIN {
+    for (i = 1; i < ARGC; i++)
+        print ARGV[i] }' a b c
+
+

输出字段分隔符为逗号

+
awk 'BEGIN { FS=":";OFS=","}
+    {print $1,$2,$3,$4}' /etc/passwd
+
+

匹配位置

+
awk 'BEGIN {
+    if (match("One Two Three", "Tw"))
+        print RSTART }'
+
+

匹配时长

+
awk 'BEGIN {
+    if (match("One Two Three", "re"))
+        print RLENGTH }'
+
+

环境变量

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
ARGC数字或参数
ARGV参数数组
FNR文件记录数(File Number of Records)
OFMT数字格式 (default "%.6g")
RSTART字符串中的位置
RLENGTH比赛时长
SUBSEP多维数组分隔符 (default "\034")
ARGIND参数索引
+

仅限 GNU awk

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
ENVIRON环境变量
IGNORECASE忽略大小写
CONVFMT转换格式
ERRNO系统错误
FIELDWIDTHS固定宽度字段
+

定义变量

+
awk -v var1="Hello" -v var2="Wold" '
+    END {print var1, var2}
+' </dev/null
+
+

使用 shell 变量

+
awk -v varName="$PWD" '
+    END {print varName}' </dev/null
+
+

Awk 运算符

+

运算符

+ + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
{print $1}第一个字段
$2 == "foo"等于
$2 != "foo"不等于
"foo" in array在数组中
+

正则表达式

+ + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
/regex/行匹配
!/regex/行不匹配
$1 ~ /regex/字段匹配
$1 !~ /regex/字段不匹配
+

更多条件

+ + + + + + + + + + + + + + + + + +
:-:-
($2 <= 4 || $3 < 20)或者
($1 == 4 && $3 < 20)
+

运算符

+

算术运算

+
    +
  • +
  • +
  • -
  • +
  • *
  • +
  • /
  • +
  • %
  • +
  • ++
  • +
  • --
  • +
+ +

速记作业

+
    +
  • +=
  • +
  • -=
  • +
  • *=
  • +
  • /=
  • +
  • %=
  • +
+ +

比较运算符

+
    +
  • ==
  • +
  • !=
  • +
  • <
  • +
  • >
  • +
  • <=
  • +
  • >=
  • +
+ +

示例

+
awk 'BEGIN {
+    if ("foo" ~ "^fo+$")
+        print "Fooey!";
+}'
+
+

不匹配

+
awk 'BEGIN {
+    if ("boo" !~ "^fo+$")
+        print "Boo!";
+}'
+
+

如果在数组中

+
awk 'BEGIN {
+    assoc["foo"] = "bar";
+    assoc["bar"] = "baz";
+    if ("foo" in assoc)
+        print "Fooey!";
+}'
+
+

Awk 函数

+

常用功能

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
函数描述
index(s,t)字符串 s 中出现字符串 t 的位置,如果未找到则为 0
length(s)字符串 s 的长度(如果没有 arg,则为 $0
rand01 之间的随机数
substr(s,index,len)返回从索引开始的 slen-char 子字符串(从 1 开始计数)
srandrand 设置种子并返回之前的种子
int(x)x 截断为整数值
split(s,a,fs)将字符串 s 拆分为数组 afs 拆分,返回 a 的长度
match(s,r)字符串 s 中出现正则表达式 r 的位置,如果未找到,则为 0
sub(r,t,s)t 替换为字符串 s 中第一次出现的正则表达式 r(如果未给出 s,则替换为 $0
gsub(r,t,s)t 替换字符串 s 中所有出现的正则表达式 r
system(cmd)执行cmd并返回退出状态
tolower(s)字符串 s 转小写
toupper(s)字符串 s 转大写
getline$0 设置为当前输入文件中的下一个输入记录
+

用户定义函数

+
awk '
+    # Returns minimum number
+    function find_min(num1, num2){
+       if (num1 < num2)
+       return num1
+       return num2
+    }
+    # Returns maximum number
+    function find_max(num1, num2){
+       if (num1 > num2)
+       return num1
+       return num2
+    }
+    # Main function
+    function main(num1, num2){
+       result = find_min(num1, num2)
+       print "Minimum =", result
+      
+       result = find_max(num1, num2)
+       print "Maximum =", result
+    }
+    # Script execution starts here
+    BEGIN {
+       main(10, 60)
+    }
+'
+
+

Awk 数组

+

带索引的数组

+
awk 'BEGIN {
+    arr[0] = "foo";
+    arr[1] = "bar";
+    print(arr[0]); # => foo
+    delete arr[0];
+    print(arr[0]); # => ""
+}'
+
+

带键的数组

+
awk 'BEGIN {
+    assoc["foo"] = "bar";
+    assoc["bar"] = "baz";
+    print("baz" in assoc); # => 0
+    print("foo" in assoc); # => 1
+}'
+
+

带拆分的数组

+
awk 'BEGIN {
+    split("foo:bar:baz", arr, ":");
+    for (key in arr)
+        print arr[key];
+}'
+
+

带有排序的数组

+
awk 'BEGIN {
+    arr[0] = 3
+    arr[1] = 2
+    arr[2] = 4
+    n = asort(arr)
+    for (i = 1; i <= n ; i++)
+        print(arr[i])
+}'
+
+

多维

+
awk 'BEGIN {
+    multidim[0,0] = "foo";
+    multidim[0,1] = "bar";
+    multidim[1,0] = "baz";
+    multidim[1,1] = "boo";
+}'
+
+

多维迭代

+
awk 'BEGIN {
+    array[1,2]=3;
+    array[2,3]=5;
+    for (comb in array) {
+        split(comb,sep,SUBSEP);
+        print sep[1], sep[2], 
+        array[sep[1],sep[2]]
+    }
+}'
+
+

Awk 条件

+

if-else 语句

+
awk -v count=2 'BEGIN {
+    if (count == 1)
+        print "Yes";
+    else
+        print "Huh?";
+}'
+
+

三元运算符

+
awk -v count=2 'BEGIN {
+    print (count==1) ? "Yes" : "Huh?";
+}'
+
+

存在

+
awk 'BEGIN {
+    assoc["foo"] = "bar";
+    assoc["bar"] = "baz";
+    if ("foo" in assoc)
+        print "Fooey!";
+}'
+
+

不存在

+
awk 'BEGIN {
+    assoc["foo"] = "bar";
+    assoc["bar"] = "baz";
+    if ("Huh" in assoc == 0 )
+        print "Huh!";
+}'
+
+

switch

+
awk -F: '{
+    switch (NR * 2 + 1) {
+        case 3:
+        case "11":
+            print NR - 1
+            break
+        case /2[[:digit:]]+/:
+            print NR
+        default:
+            print NR + 1
+        case -1:
+            print NR * -1
+    }
+}' /etc/passwd
+
+

Awk 循环

+

for...i

+
awk 'BEGIN {
+    for (i = 0; i < 10; i++)
+        print "i=" i;
+}'
+
+

1 到 100 之间的 2 的幂

+
awk 'BEGIN {
+    for (i = 1; i <= 100; i *= 2)
+        print i
+}'
+
+

for...in

+
awk 'BEGIN {
+    assoc["key1"] = "val1"
+    assoc["key2"] = "val2"
+    for (key in assoc)
+        print assoc[key];
+}'
+
+

Arguments

+
awk 'BEGIN {
+    for (argnum in ARGV)
+        print ARGV[argnum];
+}' a b c
+
+

示例

+ +

反向记录

+
awk -F: '{ x[NR] = $0 }
+    END {
+        for (i = NR; i > 0; i--)
+        print x[i]
+    }
+' /etc/passwd
+
+

反向字段

+
awk -F: '{
+    for (i = NF; i > 0; i--)
+        printf("%s ",$i);
+    print ""
+}' /etc/passwd
+
+

按记录求和

+
awk -F: '{
+    s=0;
+    for (i = 1; i <= NF; i++)
+        s += $i;
+    print s
+}' /etc/passwd
+
+

总结整个文件

+
awk -F: '
+    {for (i = 1; i <= NF; i++)
+        s += $i;
+    };
+    END{print s}
+' /etc/passwd
+
+

while

+ +
awk 'BEGIN {
+    while (a < 10) {
+        print "- " " concatenation: " a
+        a++;
+    }
+}'
+
+

do...while

+
awk '{
+    i = 1
+    do {
+        print $0
+        i++
+    } while (i <= 5)
+}' /etc/passwd
+
+

Break

+
awk 'BEGIN {
+    break_num = 5
+    for (i = 0; i < 10; i++) {
+        print i
+        if (i == break_num)
+            break
+    }
+}'
+
+

Continue

+
awk 'BEGIN {
+    for (x = 0; x <= 10; x++) {
+        if (x == 5 || x == 6)
+            continue
+        printf "%d ", x
+    }
+    print ""
+}'
+
+

Awk 格式化打印

+

用法

+

右对齐

+
awk 'BEGIN{printf "|%10s|\n", "hello"}'
+# |     hello|
+
+

左对齐

+
awk 'BEGIN{printf "|%-10s|\n", "hello"}'
+# |hello     |
+
+

通用说明符

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
特征符描述
cASCII 字符
d十进制整数
e, E, f浮点格式
o无符号八进制值
s细绳
%文字百分比
+

Space 空间

+
awk -F: '{
+    printf "%-10s %s\n", $1, $(NF-1)
+}' /etc/passwd | head -n 3
+
+

输出

+
root       /root
+bin        /bin
+daemon     /sbin
+
+

Header 标题头

+
awk -F: 'BEGIN {
+    printf "%-10s %s\n", "User", "Home"
+    printf "%-10s %s\n", "----","----"}
+    { printf "%-10s %s\n", $1, $(NF-1) }
+' /etc/passwd | head -n 5
+
+

输出

+
User       Home
+----       ----
+root       /root
+bin        /bin
+daemon     /sbin
+
+

各种各样的

+

正则表达式元字符

+
    +
  • \
  • +
  • ^
  • +
  • $
  • +
  • .
  • +
  • [
  • +
  • ]
  • +
  • |
  • +
  • (
  • +
  • )
  • +
  • *
  • +
  • +
  • +
  • ?
  • +
+ +

转义序列

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
:-:-
\b退格
\f换页
\n换行(换行)
\r回车
\t水平选项卡
\v垂直选项卡
+

运行脚本

+
$ cat demo.awk
+#!/usr/bin/awk -f
+BEGIN { x = 23 }
+      { x += 2 }
+END   { print x }
+$ awk -f demo.awk /etc/passwd
+69
+
+

另见

+ +
+ diff --git a/index.html b/index.html index cf44610b..dbb6508d 100644 --- a/index.html +++ b/index.html @@ -204,7 +204,10 @@ XPath

Linux 命令

-

+

+ +Awk + Curl Chmod @@ -221,11 +224,11 @@ Grep -find +Find -htop +Htop