AWK 常用内置字符串函数总结

AWK 常用内置字符串函数总结

AWK 提供了多种用于字符串替换、查找、截取、分割、大小写转换和格式化的内置函数。

1. 函数汇总

函数 说明 返回值
sub(Ere, Repl [, In]) 使用 Repl 替换字符串 In 中第一个匹配正则表达式 Ere 的内容。省略 In 时操作 $0 成功替换返回 1,未匹配返回 0
gsub(Ere, Repl [, In]) 使用 Repl 替换字符串 In 中所有匹配正则表达式 Ere 的内容。省略 In 时操作 $0 返回替换次数
index(String1, String2) 查找 String2String1 中第一次出现的位置。位置从 1 开始。 找到返回位置,未找到返回 0
length([String]) 返回字符串的字符长度。省略参数时返回当前记录 $0 的长度。 字符串长度
blength([String]) 返回字符串的字节长度。省略参数时使用 $0。该函数并非所有 AWK 实现都支持。 字节数
substr(String, M [, N]) 从字符串 String 的第 M 个字符开始,截取 N 个字符。省略 N 时截取到字符串末尾。 截取后的字符串
match(String, Ere) 使用正则表达式 EreString 中查找匹配内容,同时设置 RSTARTRLENGTH 找到返回起始位置,未找到返回 0
split(String, A [, Ere]) 按照分隔符 Ere 将字符串拆分到数组 A 中。省略 Ere 时使用字段分隔符 FS 分割后的元素数量
tolower(String) 将字符串中的大写字母转换为小写字母。 转换后的字符串
toupper(String) 将字符串中的小写字母转换为大写字母。 转换后的字符串
sprintf(Format, Expr, ...) 按照指定格式格式化数据,但不直接打印。 格式化后的字符串

2. sub():替换第一个匹配项

语法

sub(Ere, Repl [, In])

示例

echo "apple apple apple" |
awk '{
    sub(/apple/, "orange")
    print
}'

输出:

orange apple apple

指定操作变量:

awk 'BEGIN {
    str = "id=1001,id=1002"
    sub(/id=[0-9]+/, "id=2001", str)
    print str
}'

输出:

id=2001,id=1002

& 的作用

替换字符串中的 & 表示本次正则表达式匹配到的原始内容。

echo "id=1001" |
awk '{
    sub(/[0-9]+/, "[&]")
    print
}'

输出:

id=[1001]

3. gsub():替换所有匹配项

语法

gsub(Ere, Repl [, In])

示例

echo "apple apple apple" |
awk '{
    count = gsub(/apple/, "orange")
    print "结果:", $0
    print "替换次数:", count
}'

输出:

结果: orange orange orange
替换次数: 3

删除所有空格:

echo "a b  c" |
awk '{
    gsub(/[[:space:]]+/, "")
    print
}'

输出:

abc

sub()gsub() 的区别

函数 替换范围
sub() 只替换第一个匹配项
gsub() 替换所有匹配项

4. index():查找普通字符串

语法

index(String1, String2)

index() 查找的是普通字符串,不是正则表达式。

awk 'BEGIN {
    str = "hello world"
    print index(str, "world")
    print index(str, "linux")
}'

输出:

7
0

位置从 1 开始。


5. length():获取字符串长度

语法

length([String])

指定字符串:

awk 'BEGIN {
    print length("hello")
}'

输出:

5

不指定参数时,计算当前记录 $0 的长度:

echo "hello awk" |
awk '{
    print length()
}'

输出:

9

计算字段长度:

echo "1001 storage" |
awk '{
    print length($1)
    print length($2)
}'

输出:

4
7

6. blength():获取字节长度

语法

blength([String])

blength() 用于计算字符串占用的字节数。

需要注意:

  • length() 通常计算字符数量。
  • blength() 计算字节数量。
  • blength() 不是 POSIX AWK 标准函数。
  • GNU AWK 通常没有 blength() 函数。
  • 某些系统的 AWK,例如部分 AIX AWK 实现,可能支持该函数。

为了保证脚本可移植性,不建议依赖 blength()


7. substr():截取字符串

语法

substr(String, M [, N])

其中:

  • M:开始位置,从 1 开始。
  • N:截取长度,可以省略。

指定长度:

awk 'BEGIN {
    str = "abcdefgh"
    print substr(str, 3, 4)
}'

输出:

cdef

省略长度:

awk 'BEGIN {
    str = "abcdefgh"
    print substr(str, 3)
}'

输出:

cdefgh

提取固定格式字符串:

awk 'BEGIN {
    node = "node1001"
    print substr(node, 5)
}'

输出:

1001

8. match():使用正则表达式查找

语法

match(String, Ere)

执行后会设置两个特殊变量:

变量 说明
RSTART 匹配内容的起始位置
RLENGTH 匹配内容的长度
匹配失败时 RSTART0RLENGTH-1

示例:

awk 'BEGIN {
    str = "node_id=1001"

    pos = match(str, /[0-9]+/)

    print "返回位置:", pos
    print "RSTART:", RSTART
    print "RLENGTH:", RLENGTH
    print "匹配内容:", substr(str, RSTART, RLENGTH)
}'

输出:

返回位置: 9
RSTART: 9
RLENGTH: 4
匹配内容: 1001

匹配失败:

awk 'BEGIN {
    str = "node_id=abc"
    print match(str, /[0-9]+/)
    print RSTART
    print RLENGTH
}'

输出:

0
0
-1

index()match() 的区别

函数 匹配类型
index() 普通字符串
match() 正则表达式

9. split():分割字符串

语法

split(String, A [, Ere])

按逗号分割:

awk 'BEGIN {
    str = "1001,1002,1003"
    count = split(str, nodes, ",")

    print "元素数量:", count

    for (i = 1; i <= count; i++) {
        print nodes[i]
    }
}'

输出:

元素数量: 3
1001
1002
1003

按多个空格分割:

awk 'BEGIN {
    str = "meta   storage  mgmtd"
    count = split(str, arr, /[[:space:]]+/)

    for (i = 1; i <= count; i++) {
        print arr[i]
    }
}'

输出:

meta
storage
mgmtd

省略分隔符时使用 FS

awk 'BEGIN {
    FS = ":"
    count = split("1001:storage:8000", arr)

    for (i = 1; i <= count; i++) {
        print arr[i]
    }
}'

10. tolower():转换为小写

语法

tolower(String)

示例:

awk 'BEGIN {
    type = "STORAGE"
    print tolower(type)
}'

输出:

storage

原变量不会自动修改:

awk 'BEGIN {
    type = "STORAGE"
    lower = tolower(type)

    print type
    print lower
}'

输出:

STORAGE
storage

如需修改原变量,应重新赋值:

type = tolower(type)

11. toupper():转换为大写

语法

toupper(String)

示例:

awk 'BEGIN {
    type = "storage"
    print toupper(type)
}'

输出:

STORAGE

修改原变量:

type = toupper(type)

12. sprintf():格式化并返回字符串

语法

sprintf(Format, Expr, ...)

sprintf()printf 的主要区别:

函数 行为
printf() 格式化并直接输出
sprintf() 格式化后返回字符串,不直接输出

格式化整数:

awk 'BEGIN {
    disk_id = sprintf("%02d", 3)
    print disk_id
}'

输出:

03

拼接节点目录名:

awk 'BEGIN {
    node_id = 1001
    disk_id = 3

    path = sprintf("tyas_%d_%02d", node_id, disk_id)
    print path
}'

输出:

tyas_1001_03

常用格式符:

格式符 说明
%s 字符串
%d 十进制整数
%f 浮点数
%.2f 保留两位小数
%x 十六进制整数
%o 八进制整数
%02d 至少两位,不足时前面补 0
%-10s 字符串左对齐,宽度为 10
%10s 字符串右对齐,宽度为 10

13. 综合示例:解析配置项

假设配置文件内容如下:

[numa]
node_id = 1
cpu_list = 0-15

读取 node_id

awk '
    /^[[:space:]]*\[/ {
        section = $0
        gsub(/^[[:space:]]*\[|\][[:space:]]*$/, "", section)
        next
    }

    section == "numa" && /^[[:space:]]*node_id[[:space:]]*=/ {
        line = $0
        sub(/^[^=]*=/, "", line)
        gsub(/^[[:space:]]+|[[:space:]]+$/, "", line)
        print line
    }
' node.toml

输出:

1

这里使用了:

  • gsub():去除节名两侧的 [] 和空白。
  • sub():删除等号左边的内容。
  • gsub():删除值两侧的空白。
  • print:输出最终结果。

14. 使用注意事项

14.1 字符串位置从 1 开始

以下函数返回或使用的位置都从 1 开始:

index()
substr()
match()
RSTART

14.2 sub()gsub() 会修改目标变量

sub(/old/, "new", str)
gsub(/old/, "new", str)

这两个函数会直接修改 str

而下面这些函数通常只是返回一个新值,不会修改原字符串:

substr()
tolower()
toupper()
sprintf()

例如:

lower = tolower(str)

14.3 省略操作字符串时默认操作 $0

sub(/abc/, "xyz")
gsub(/abc/, "xyz")

等价于:

sub(/abc/, "xyz", $0)
gsub(/abc/, "xyz", $0)

14.4 正则表达式的写法

正则表达式常用斜杠表示:

/[0-9]+/

正则表达式也可以保存在变量中:

pattern = "^[[:space:]]*node_id[[:space:]]*="
if ($0 ~ pattern) {
    print
}

15. 快速记忆

sub       替换第一个匹配项
gsub      替换所有匹配项
index     查找普通字符串位置
length    获取字符长度
blength   获取字节长度,兼容性较差
substr    截取子字符串
match     使用正则查找,并设置 RSTART、RLENGTH
split     将字符串分割为数组
tolower   转换成小写
toupper   转换成大写
sprintf   格式化并返回字符串
posted @ 2026-06-17 14:05  苏格拉底的落泪  阅读(11)  评论(0)    收藏  举报