跳到主要内容

awk + sed 命令速查 , 80+ 条文本处理一行命令(Linux 和 macOS 都能跑)

awk + sed 命令速查,80+ 条文本处理一行命令,真实例子和常见坑。

  • 本地处理
  • 分类 开发运维
  • 适合 格式化、校验、压缩或检查和代码相关的文本。
工具:
分类:
168 条命令
sed · 基础 (26)
sed 's/old/new/' file

每行只替换第一次出现的 old 为 new。sed 默认行为:逐行、只换首个。

输入
old old old
foo old bar old
输出
new old old
foo new bar old
例子
sed 's/cat/dog/' pets.txt
echo 'hello world' | sed 's/world/sed/'
sed 's/old/new/g' file

全局替换,每行的所有出现都换,不止首个。最常用的 g flag。

输入
old old old
输出
new new new

常见坑: 忘 g 是 sed 最常见的踩坑。在 CSV 行上跑 `sed s/,/|/` 只换第一个逗号,后面全留着。

例子
sed 's/ /_/g' file.txt
sed -i 's/http:/https:/g' index.html
sed 's/old/new/2' file

只替换每行的第 N 次匹配(这里第 2 次)。数字 flag。

输入
a a a a
输出
a new a a
例子
sed 's/,/|/3' csv-row.txt   # change only the 3rd comma
sed 's/old/new/3g' file

N 和 g 组合:从第 N 次匹配起一直替换到行末。

输入
x x x x x
输出
x x new new new
例子
sed 's/ /_/2g' file   # keep first space, underscore the rest
sed -n '5p' file

只打第 5 行。-n 关掉默认打印,p 打地址匹配。

输入
a
b
c
d
e
f
输出
e
例子
sed -n '5p' /etc/passwd
sed -n '100,200p' big.log   # range
sed -n '10,20p' file

打第 10 到第 20 行(含两端)。比 head + tail 干脆。

输入
(file with 30 lines)
输出
(lines 10 through 20)
例子
sed -n '10,20p' big.log
sed -n '/START/,/END/p' file   # regex range
sed '5d' file

删第 5 行,其他原样打出来。

输入
a
b
c
d
e
输出
a
b
c
d
例子
sed '1d' file.csv         # strip header row
sed '$d' file           # drop last line
sed '/^$/d' file

删空行(^$ 之间无字符)。

输入
a

b

c
输出
a
b
c

常见坑: 只命中真的空行。带空格/制表符的"看着空"的行要用 `/^[[:space:]]*$/d`。

例子
sed '/^$/d' notes.md
sed '/^[[:space:]]*$/d' file   # also blanks
sed '/pattern/d' file

删每一行匹配正则的行。

输入
ok 1
err 2
ok 3
err 4
输出
ok 1
ok 3
例子
sed '/^#/d' config           # drop comment lines
sed '/DEBUG/d' app.log
sed '5i\ NEW LINE' file

在第 5 行前插一行新内容。i\\ 后面的文字就是要插的行。

输入
a
b
c
d
e
f
输出
a
b
c
d
NEW LINE
e
f
例子
sed '1i\
#!/bin/bash' script.sh   # add shebang at top
sed '5a\ appended text' file

在第 5 行后追加一行新内容。

输入
1
2
3
4
5
6
输出
1
2
3
4
5
appended text
6
例子
sed '$a\
EOF marker' file   # append at end
sed '5c\ replacement' file

把匹配的整行整个替换成新文本。

输入
a
b
old line
d
输出
a
b
replacement
d
例子
sed '/^TODO/c\
DONE' tasks.md
sed 'y/abc/xyz/' file

字符转换:a→x、b→y、c→z。像 sed 内置的 tr。

输入
cab cab
输出
zxy zxy
例子
sed 'y/abcdefghijklmnopqrstuvwxyz/ABCDEFGHIJKLMNOPQRSTUVWXYZ/' file   # upper-case
sed -E 's/[0-9]+/N/g' file

用 -E 开扩展正则:把任意一串数字换成 N。-E 后 +、?、| 不用加反斜杠。

输入
order 42 then 1337
输出
order N then N

常见坑: GNU sed 接受 -r 作为 -E 的别名,BSD 只认 -E。可移植脚本一律写 -E。

例子
sed -E 's/(\w+)@(\w+)/REDACTED/g' file
sed -n '1,5p' file

打前 5 行,相当于 head -5。-n 关默认打印,范围地址挑第 1 到第 5 行。

输入
a
b
c
d
e
f
g
输出
a
b
c
d
e
例子
sed -n '1,5p' file
sed '5q' file   # quit after line 5, even faster
sed '5q' file

打前 5 行后退出。比范围地址快,大文件读到第 5 行就停,不会扫到底。

输入
(file with 1M lines)
输出
(first 5 lines only)
例子
sed '10q' big.log
sed '/READY/q' boot.log   # quit at first READY
sed -n '2~3p' file

GNU 步进地址:打第 2 行,之后每隔 3 行打一次(2、5、8 …)。`first~step` 是 GNU 扩展。

输入
l1
l2
l3
l4
l5
l6
l7
l8
输出
l2
l5
l8

常见坑: `~` 步进地址只 GNU 有。BSD/macOS sed 会报错,要可移植就用 awk `NR%3==2`。

例子
sed -n '1~2p' file   # odd lines
sed -n '0~2p' file   # even lines (GNU)
sed '2,4d' file

删一段行(第 2 到第 4),其余原样打出。

输入
a
b
c
d
e
输出
a
e
例子
sed '1,10d' file   # drop first 10 lines
sed '2,$d' file   # keep only line 1
sed -n 'p' file

每行打一次。-n 关了默认打印,p 再补回来,等于 cat。

输入
a
b
输出
a
b

常见坑: 去掉 -n 后 `sed p` 每行打两遍:默认打印加显式 p。很常见的手滑。

例子
sed -n 'p' file   # = cat
sed 'p' file   # every line doubled
sed 's/old/new/I' file

用 I flag 做大小写不敏感替换(GNU)。Old、OLD、old 都命中。

输入
Old OLD old
输出
new new new

常见坑: I flag 是 GNU sed 的。BSD/macOS 不支持,退而用字符类 `s/[Oo]ld/new/g`。

例子
sed 's/error/ERR/Ig' app.log
sed 's/.*/[&]/' file

把每整行用方括号包起来。替换里的 & 代表"整段匹配到的文本"。

输入
hello
world
输出
[hello]
[world]
例子
sed 's/[0-9]*/<&>/' file   # bracket the leading number
sed 's/\(.*\)/\1\1/' file

用反向引用把每行内容复制一遍。`\(.*\)` 捕获整行,`\1\1` 打两遍。

输入
ab
输出
abab
例子
sed -E 's/(.*)/\1 \1/' file   # space between copies, ERE
sed -n '/foo/,+2p' file

打匹配 /foo/ 的行加后面 2 行。`+N` 相对范围是 GNU 扩展。

输入
a
foo
b
c
d
输出
foo
b
c

常见坑: `addr,+N` 只 GNU 有。BSD 上用 `sed -n "/foo/{N;N;p;}"` 抓固定条数的后续行。

例子
grep -A2 foo file   # the grep equivalent
sed '/foo/!d' file

删掉不匹配 /foo/ 的行,只留匹配行。`!` 对地址取反,不匹配的被删。

输入
foo 1
bar 2
foo 3
输出
foo 1
foo 3
例子
sed '/^#/!d' config   # keep only comment lines
sed 's/^[ \t]*//' file

去掉每行开头的空白(左 trim)。和行尾去空白配套用。

输入
    hi
	bye
输出
hi
bye
例子
sed -E 's/^[[:space:]]+//' file   # POSIX class, portable
sed -n '/foo/I p' file

大小写不敏感地打匹配 /foo/ 的行(GNU 的 I 地址修饰符)。

输入
Foo
bar
FOO
输出
Foo
FOO
例子
sed -n '/error/Ip' app.log
sed · 高级 (24)
sed -i 's/old/new/g' file

原地修改文件,直接覆盖原文件。GNU sed 写法。

常见坑: macOS / BSD 上这条会挂。BSD sed 要扩展名参数:`sed -i "" "s/a/b/" file`(空串)或 `sed -i.bak`。最稳:`sed -i.bak`,两边都跑得起来。

例子
sed -i 's/foo/bar/g' file.txt
sed -i.bak 's/foo/bar/g' file.txt   # portable
sed -i '' 's/old/new/g' file

BSD / macOS 的原地修改。那个空字符串 `""` 是备份扩展名,在 macOS 上必须有。

输入
hello old world
输出
(file rewritten to: hello new world)
例子
sed -i '' 's/http:/https:/g' index.html
sed -n '/start/,/end/p' file

正则地址范围,从首次 /start/ 到下次 /end/ 之间的行全打出来。

输入
a
start
b
c
end
d
输出
start
b
c
end
例子
sed -n '/BEGIN CERTIFICATE/,/END CERTIFICATE/p' chain.pem
sed -n '/pattern/{N;p;}' file

行匹配 /pattern/ 时,用 N 把下一行也拉进 pattern space,再 p 把两行一起打。

例子
sed -n '/ERROR/{N;p;}' app.log   # show ERROR plus the next line
sed 'N;s/\n/ /' file

把每两行拼成一行,空格连接。N 把两行读进 pattern space,把里面那个换行换成空格。

输入
name
Lei
role
dev
输出
name Lei
role dev
例子
sed 'N;s/\n/ /' two-line-records.txt
sed '/start/,/end/{//!d}' file

删除块的"主体",保留首尾标记。`//!d` 表示"不匹配最近正则的行都删"。

例子
sed '/^BEGIN/,/^END/{//!d}' file
sed '1!G;h;$!d' file

经典 sed 一行:用 hold space(h、G)把文件按行反转。

输入
1
2
3
输出
3
2
1
例子
sed '1!G;h;$!d' file   # like `tac`
sed -e 's/a/b/' -e 's/c/d/' file

一次跑多条替换,顺序敏感。-e 可以叠任意条。

例子
sed -e 's/foo/bar/g' -e 's/baz/qux/g' file
sed -f script.sed file

从文件里读 sed 命令(每行一条)。复杂处理放文件好维护、好 git。

例子
sed -f rewrites.sed input.txt > output.txt
sed 'H;1h;$!d;x;s/\n/, /g' file

把整个文件折成一行用逗号连接(hold space 累加器写法)。

输入
a
b
c
输出
a, b, c
例子
sed 'H;1h;$!d;x;s/\n/, /g' names.txt
sed -E 's|http://([^/]+)/|https://\1/|g' file

把 | 当分隔符,URL 里的斜杠不用转义。\1 引用第一组捕获(主机名)。

输入
http://example.com/page
输出
https://example.com/page

常见坑: sed 把 s 后面跟的第一个字符当分隔符。挑数据里没有的字符:|、#、!、@ 都常用。

例子
sed 's|/usr/local|/opt|g' paths.conf
sed -i.bak 's/old/new/g' *.md

原地改当前目录所有 .md,留 .md.bak 备份。GNU 和 BSD 都能跑。

常见坑: glob 展到很多文件时备份也跟着爆。改完确认无误后 `rm *.md.bak` 清干净。

例子
sed -i.bak 's/2025/2026/g' docs/*.md && rm docs/*.md.bak
sed ':a;N;$!ba;s/\n/ /g' file

把整个文件读进 pattern space(标签 :a + N + 分支 ba 循环到最后一行),再把所有换行换成空格,折成一行。

输入
a
b
c
输出
a b c
例子
sed ':a;N;$!ba;s/\n/,/g' file   # comma-join the whole file
sed -E 's/([0-9]{4})-([0-9]{2})-([0-9]{2})/\3\/\2\/\1/' file

把 ISO 日期(YYYY-MM-DD)重排成 DD/MM/YYYY,靠三个捕获组加反向引用。

输入
2026-05-30
输出
30/05/2026
例子
sed -E 's/(....)-(..)-(..)/\2\/\3\/\1/' dates.txt   # to MM/DD/YYYY
sed -n 'l' file

以无歧义形式打印:tab 显示成 \t,行尾显示成 $,不可打印字节显示成八进制转义。查隐藏字符神器。

输入
(line with a tab)
输出
col1\tcol2$
例子
sed -n 'l' suspicious.txt   # reveal tabs and CR
cat -A file   # similar idea
sed 's/\r$//' file

去掉行尾回车符,把 Windows 的 CRLF 换行转成 Unix 的 LF。

输入
line\r
输出
line

常见坑: BSD sed 不认 `\r`。macOS 上用字面回车:`sed $'s/\r$//'`,或直接 `tr -d '\r'`。

例子
sed -i 's/\r$//' file.txt   # dos2unix, GNU
sed 's/$/\r/' file   # unix2dos
sed -n '/foo/{=;p;}' file

每个匹配 /foo/ 的行,先打行号(=)再打内容(p),相当于带行号的 grep,一次命中两行输出。

输入
a
foo
b
foo
输出
2
foo
4
foo
例子
sed -n '/ERROR/{=;p;}' app.log
sed '/^$/{N;/^\n$/D}' file

把连续空行压成一个空行。遇空行读下一行,两行都空就删头一行,D 循环处理。

输入
a



b
输出
a

b
例子
cat -s file   # the simpler equivalent on GNU coreutils
sed 'n;d' file

隔行删,保留奇数行。n 打当前行并读下一行,d 把下一行删掉。

输入
1
2
3
4
5
输出
1
3
5
例子
sed 'n;d' file   # keep odd lines
sed '1d;n;d' file   # keep even lines
sed -E 's/([a-z])([A-Z])/\1_\2/g' file

在小写字母和大写字母之间插下划线,把 camelCase 拆向 snake_case(大小写再单独处理)。

输入
fooBarBaz
输出
foo_Bar_Baz
例子
sed -E 's/([a-z])([A-Z])/\1_\2/g' file | sed 's/.*/\L&/'   # full snake_case, GNU \L
sed 's/\(.\)/\1\n/g' file

把每个字符拆到单独一行,在每个字符后插换行(GNU sed 替换里认 \n)。

输入
abc
输出
a
b
c

常见坑: 替换里的字面 `\n` 是 GNU 扩展。BSD 上要在脚本里用反斜杠加真换行插入。

例子
sed 's/\(.\)/\1\n/g' file   # one char per line, GNU
sed '0~2d' file

删每个偶数行(留奇数行),用 GNU 的 `first~step` 地址,从 0 起步长 2。

输入
1
2
3
4
输出
1
3

常见坑: 只 GNU 有的地址。BSD/macOS 改用 awk `NR%2`。

例子
sed '1~2d' file   # delete odd lines, keep even
sed -E 's/(.)\1+/\1/g' file

把连续重复的同一字符压成一个。`(.)` 捕一个字符,`\1+` 匹配它的重复,只留一个。

输入
aaabbbcccd
输出
abcd
例子
echo 'heelllooo' | sed -E 's/(.)\1+/\1/g'   # helo
sed -e '1{h;d;}' -e '2{H;x;}' file

用 hold space 交换前两行:第 1 行先存起来(h;d),第 2 行追加(H)再交换(x)。

输入
one
two
three
输出
two
one
three
例子
sed -e '1{h;d;}' -e '2{H;x;}' file
sed · 一行命令 (24)
sed '$d' file

删最后一行。$ 是地址"最后一行"。

输入
a
b
c
d
输出
a
b
c
例子
sed '$d' file.log
sed -n '$=' file

数文件行数。= 打当前行号,$ 限制到最后一行。

输入
a
b
c
d
输出
4
例子
sed -n '$=' file
sed = file | sed 'N;s/\n/\t/'

给文件加行号(穷人版 nl)。第一个 sed 插数字行,第二个把两行合一。

输入
a
b
c
输出
1	a
2	b
3	c
例子
sed = file | sed 'N;s/\n/\t/'
sed -n '/pattern/p' file

相当于 grep pattern file,只打匹配行。pipeline 里已经有 sed 时这条好用。

例子
sed -n '/ERROR/p' app.log
sed -n '/^From: /,/^$/p' mbox

打每封邮件的 header 块,从 From: 行到下一空行。

例子
sed -n '/^From: /,/^$/p' inbox.mbox
sed -n '/foo/=' file

打匹配行的行号(不打内容)。

输入
a
foo
b
foo bar
c
输出
2
4
例子
sed -n '/TODO/=' notes.md
sed 's/^/ /' file

每行前补 4 个空格(贴 Markdown 代码块时常用)。

输入
a
b
输出
    a
    b
例子
sed 's/^/    /' snippet.txt
sed 's/[ \t]*$//' file

去掉每行末尾的空白,干掉那些看不见的行尾空格。

例子
sed -i 's/[ \t]*$//' src/**/*.py
sed -n '1!G;h;$p' file

把文件按行倒序,和 tac 一样,在没装 tac 的 BSD 上能用。

例子
sed -n '1!G;h;$p' file
sed 'G' file

给文件加双倍行距,每行后加一行空。

输入
a
b
输出
a

b
例子
sed 'G' notes.txt
sed -n '/^$/!p' file

只打非空行,跳空行的短写法。

例子
sed -n '/^$/!p' file
sed -e :a -e '$!N;s/\n/ /;ta' file

把全文所有行折成一行用空格连(用标签 :a + 分支 ta 做循环)。

例子
sed -e :a -e '$!N;s/\n/ /;ta' lines.txt
sed -n '2p' file

只打第 2 行。换数字就能取任意单行。

输入
a
b
c
输出
b
例子
sed -n '1p' file   # first line
sed -n '3p;7p' file   # lines 3 and 7
sed -n '$p' file

打文件最后一行(sed 版 tail -1)。$ 是"最后一行"地址。

输入
a
b
c
输出
c
例子
sed -n '$p' file
sed 's/^/> /' file

每行前加 "> ",像邮件引用一样把文本引起来。

输入
hi
there
输出
> hi
> there
例子
sed 's/^/> /' quote.txt
sed 's/$/;/' file

每行末尾加分号。这里的 $ 是行尾锚点。

输入
a
b
输出
a;
b;
例子
sed 's/$/,/' col.txt   # turn a column into CSV-ish
sed 's/ */ /g' file

把多个空格压成一个,快速规整空白。

输入
a    b   c
输出
a b c
例子
sed -E 's/ +/ /g' file   # same with ERE
sed -n '1p;$p' file

一遍打出文件的首行和末行。

输入
a
b
c
d
输出
a
d
例子
sed -n '1p;$p' big.log
sed 's/\t/,/g' file

把制表符换成逗号,字段不含逗号时的快速 TSV 转 CSV。

输入
a	b	c
输出
a,b,c

常见坑: BSD sed 不展开 `\t`,macOS 上敲真 Tab 或用 `sed $'s/\t/,/g'`。

例子
sed $'s/\t/,/g' in.tsv > out.csv   # portable
sed -n '/^$/=' file

打所有空行的行号,方便找段落分隔位置。

输入
a

b


c
输出
2
4
5
例子
sed -n '/^$/=' essay.txt
sed '/foo/r insert.txt' file

在每个匹配 /foo/ 的行之后,读入并插入 insert.txt 整个内容。`r` 命令追加一个文件。

例子
sed '/<!-- INCLUDE -->/r snippet.html' page.html
sed -n '/foo/,/bar/{/foo/d;/bar/d;p;}' file

打 /foo/ 和 /bar/ 之间的行,去掉这两条边界行本身。

输入
x
foo
A
B
bar
y
输出
A
B
例子
sed -n '/BEGIN/,/END/{/BEGIN/d;/END/d;p;}' block.txt
sed '$!N;/^\(.*\)\n\1$/!P;D' file

删相邻的重复行(sed 版 uniq)。用反向引用把每行和下一行比较。

输入
a
a
b
b
b
c
输出
a
b
c
例子
sed '$!N;/^\(.*\)\n\1$/!P;D' file   # = uniq for adjacent dups
sed 's/\(.*\):.*/\1/' file

保留每行最后一个冒号之前的内容(贪婪 `.*` 吃到最后一个冒号)。

输入
a:b:c
输出
a:b
例子
sed 's/:[^:]*$//' file   # same: drop after last colon
sed · 常见坑 (10)
GNU sed -i vs BSD sed -i

GNU `sed -i "…"` 直接跑;BSD/macOS `sed -i "…"` 必须在 -i 紧后给扩展名参数(不要备份就写 `""`)。

常见坑: 不可移植的 sed -i 是跨平台脚本最常翻的车。统一写 sed -i.bak,GNU 和 BSD 都吃,跑完 rm *.bak 收尾。

例子
sed -i.bak 's/old/new/g' file   # portable
case $(sed --version 2>&1) in *GNU*) SED='sed -i' ;; *) SED="sed -i ''" ;; esac
Regex dialect: BRE vs ERE

sed 默认 BRE(基础正则):+、?、|、()、{} 都是字面字符,要加反斜杠才变元字符。-E 切 ERE 才是平时熟的那个。

常见坑: `sed s/foo+/bar/` 不会匹配 foooo,它在找字面串 `foo+`。要么 `\+`(GNU),要么 `sed -E s/foo+/bar/`。

例子
sed -E 's/(foo)+/bar/' file   # works on both GNU and BSD
Slash collision in URLs

模式或替换里有 / 时换分隔符。sed 让你用 s 后面紧跟的任意字符当分隔符。

常见坑: `sed s/http:\/\/a\.com/b.com/g` 没法读。`sed s|http://a.com|b.com|g` 一模一样的效果,看着舒服。

例子
sed 's|http://|https://|g' file
sed 's#/var/log#/opt/log#g' config
Greedy match swallows too much

sed 正则是贪婪的,BRE/ERE 里没有 ? 懒惰修饰。`.*` 拿的是最长串,不是最短。

常见坑: `sed "s/<.*>//" "<a><b>"` 把整段 <a><b> 都删了,不是只删 <a>。用 [^>]* 才对:`s/<[^>]*>//`。

例子
sed 's/<[^>]*>//g' page.html   # strip tags, no greediness trap
Backreferences need escaped parens in BRE

BRE 默认下捕获组写 `\(...\)`,反向引用 `\1`。ERE(-E)下直接 `(…)`。

例子
sed 's/\(foo\)\(bar\)/\2\1/' file        # BRE
sed -E 's/(foo)(bar)/\2\1/' file       # ERE, clearer
Anchors inside a multiline pattern space

N 把第二行拉进 pattern space 后,`^` 和 `$` 仍只匹配最开头和最末尾,不是每个内嵌行。要定位内部行界得用 `\n`。

常见坑: 很多人以为 N 之后 `s/^/> /g` 给两行都加前缀。它只给第一行加。要够到第二行得匹配 `\n`:`s/\n/\n> /`。

例子
sed 'N;s/^/> /;s/\n/\n> /' file
Last line has no trailing newline

输入文件结尾没有换行时,sed 原样保留,输出也缺末尾换行,可能搞坏后面期待换行的工具。

常见坑: 结尾缺换行的文件喂给循环时,最后一条记录可能被悄悄丢掉。用 `sed -e '$a\' file`(GNU)或 `printf '\n' >> file` 规整。

例子
[ -n "$(tail -c1 file)" ] && echo >> file   # add newline if missing
Single-quote escaping in sed scripts

单引号里 shell 原样传 sed 脚本,但里面不能直接放单引号。得收尾引号、转义、再开:`'\''`。

常见坑: 要替换一个单引号得写一串四字符:`sed 's/x/'\''/g'`。或者整段改双引号,转义 `$` 和反斜杠。

例子
sed "s/x/'/g" file   # double-quote the whole script
sed is line-oriented, not whole-file

sed 默认逐行处理,正则跨不了换行,除非先用 N 或循环把更多行拉进 pattern space。

常见坑: `sed "s/foo\nbar/X/"` 默认永远不匹配,因为 foo 和 bar 在不同行。先把文件读进来:`sed ":a;N;$!ba;s/foo\nbar/X/"`。

例子
sed ':a;N;$!ba;s/foo\nbar/X/g' file   # cross-line match
Special chars in the REPLACEMENT side

替换部分里 `&`、`\` 和分隔符都是特殊字符。要输出字面 & 得写 `\&`,否则 & 会把整段匹配重新塞回去。

常见坑: `sed "s/price/price & tax/"` 会变成 "price price tax",裸 & 展开了。转义它:`s/price/price \& tax/`。

例子
sed 's/x/A \& B/' file   # literal ampersand
awk · 基础 (25)
awk '{ print $1 }' file

每行打第一个字段。默认按空白分字段。

输入
alice 30 dev
bob 28 ops
输出
alice
bob
例子
awk '{ print $1 }' /etc/passwd   # actually need -F:
ls -l | awk '{ print $9 }'
awk '{ print $NF }' file

每行打最后一个字段。NF 是字段总数。

输入
a b c
1 2 3 4
输出
c
4
例子
ls -l | awk '{ print $NF }'   # filenames
awk 'NR==5' file

只打第 5 行。NR 是记录计数(默认 RS 时等于行号)。

输入
a
b
c
d
e
f
输出
e
例子
awk 'NR==5'  file
awk 'NR>=10 && NR<=20' file   # range
awk 'END { print NR }' file

数行数(等于 wc -l),在 END 块里打 NR 的最终值。

输入
a
b
c
输出
3
例子
awk 'END { print NR }' file
awk -F, '{ print $2 }' file.csv

把逗号当字段分隔符(CSV),打第二列。-F 在启动时设 FS。

输入
alice,30,dev
bob,28,ops
输出
30
28

常见坑: -F 默认按字面字符切;-F"\t" 要加引号。要正则分隔符用 -F"[,;]"(awk 内置 ERE)。

例子
awk -F, '{ print $1, $3 }' data.csv
awk -F: '{ print $1 }' /etc/passwd
awk 'BEGIN { print "hi" }'

在读输入之前跑一段。常用来打表头、设常量,或者当无输入的计算器。

输出
hi
例子
awk 'BEGIN { print 2+2 }'   # 4
awk 'BEGIN { for(i=1;i<=5;i++) print i }'
awk '/pattern/ { print }' file

打匹配正则的行(基本等同 grep)。默认动作是 print,所以 `awk /pattern/` 也行。

例子
awk '/ERROR/' app.log
awk '/^200/ { print $7 }' access.log
awk '/start/,/end/' file

范围模式,从首次 /start/ 到下次 /end/ 之间的行(含)全打。

例子
awk '/BEGIN/,/END/' file
awk '{ printf "%-10s %5d\n", $1, $2 }' file

用 printf 格式化:第一列左对齐宽 10,第二列右对齐 5 位整数。

输入
alice 30
bob 285
输出
alice          30
bob           285
例子
awk '{ printf "%s=%d\n", $1, $2 }' kv.txt
awk 'BEGIN { FS=","; OFS="|" } { $1=$1; print }' file

把 CSV 改成 | 分隔。诀窍:OFS 只在你"重新赋值字段"时才生效,所以写 $1=$1 触发一下。

输入
a,b,c
1,2,3
输出
a|b|c
1|2|3

常见坑: 不写 $1=$1 输出就是原行没变,这个坑第一次踩能耗 30 分钟。

例子
awk 'BEGIN{FS=",";OFS="\t"} {$1=$1;print}' a.csv > a.tsv
awk -v name=lei '{ print name, $0 }' file

用 -v 把 shell 变量传进 awk,比在 awk 程序里硬塞 shell 引号干净。

例子
awk -v user="$USER" '{ print user, $1 }' file
awk -v d=$(date +%F) 'BEGIN{ print d }'
awk 'NF' file

打有字段的行,即跳空行。NF > 0 时为真。

输入
a

b

c
输出
a
b
c
例子
awk 'NF' messy.txt > clean.txt
awk '{ print NR, $0 }' file

给每行前面加行号,等效 cat -n 的简写。

输入
a
b
c
输出
1 a
2 b
3 c
例子
awk '{ print NR, $0 }' notes.md
awk '{ print $2, $1 }' file

调换前两列。print 里的逗号会在两者间插 OFS(默认空格)。

输入
alice 30
bob 28
输出
30 alice
28 bob
例子
awk '{print $2, $1}' names.txt
awk 'NF > 3' file

打字段数超过 3 的行,用来挑出比预期还宽的畸形行。

输入
a b c
a b c d e
输出
a b c d e
例子
awk -F, 'NF != 5' data.csv   # rows that are not exactly 5 columns
awk '$2 == "dev"' file

打第二字段等于字符串 "dev" 的行。字符串比较要把值放双引号里。

输入
alice dev
bob ops
cara dev
输出
alice dev
cara dev
例子
awk '$3 == "200"' access.log   # exact status match
awk '$1 ~ /^a/' file

打第一字段匹配正则的行(这里:以 a 开头)。`~` 是匹配运算符,`!~` 是不匹配。

输入
alice 1
bob 2
amy 3
输出
alice 1
amy 3
例子
awk '$0 !~ /DEBUG/' app.log   # drop DEBUG lines
awk 'BEGIN { print 2**10 }'

awk 当计算器:`**`(以及 `^`)是乘方,打出 1024。

输出
1024
例子
awk 'BEGIN { print sqrt(2), 7%3, int(3.9) }'   # 1.41421 1 3
awk '{ print FNR, FILENAME, $0 }' a.txt b.txt

打每行时带上该文件内的行号(FNR)和来源文件名(FILENAME)。多文件输入时好用。

例子
awk '{print FILENAME":"FNR": "$0}' *.log   # grep -Hn style
awk 'NR >= 10 && NR <= 20' file

用 NR 数值条件打第 10 到第 20 行,等同 `sed -n "10,20p"`。

输入
(30-line file)
输出
(lines 10 through 20)
例子
awk 'NR>=10 && NR<=20' big.log
awk 'END { print $0 }' file

打文件最后一行。END 里 `$0` 仍保存着 awk 读到的最后一条记录。

输入
a
b
c
输出
c
例子
awk 'END{print $0}' file   # like tail -1
awk -F'\t' '{ print $1 }' file.tsv

按制表符分列并打第 1 列,处理 TSV 的正确分隔符。

输入
a	b	c
输出
a
例子
awk -F'\t' '{print $2}' data.tsv
awk '$3 > 100' file

打第三字段数值大于 100 的行。两边都像数字时 awk 按数值比较。

输入
a 1 50
b 2 150
c 3 99
输出
b 2 150
例子
awk '$NF > 1000' sizes.txt
awk '{ $2=""; print }' file

把第 2 字段清空。给字段赋值会用 OFS 重建 $0,原字段位置留下一个双分隔符。

输入
a b c
输出
a  c

常见坑: 这会留下一个双空格,不是真删一列。要真正去掉一列得把后面的字段前移或手动重建记录。

例子
awk '{$2=$3; $3=""; print}' file   # crude column drop
awk 'BEGIN { print ENVIRON["HOME"] }'

通过内置 ENVIRON 数组读环境变量,不用 -v 中转。

例子
awk 'BEGIN { print ENVIRON["USER"], ENVIRON["PWD"] }'
awk · 高级 (25)
awk '{ c[$1]++ } END { for (k in c) print k, c[k] }' file

统计第一列出现次数,典型 group by。关联数组以值为 key。

输入
apple
banana
apple
cherry
banana
apple
输出
apple 3
banana 2
cherry 1
例子
awk '{ c[$7]++ } END { for (k in c) print k, c[k] }' access.log   # URL frequency
awk 'NR==FNR { a[$1]=$2; next } { print $0, a[$1] }' map.txt data.txt

双文件 join:先把 map.txt 读进数组 a,再给 data.txt 每行带上对应值。FNR==NR 只在读第一个文件时成立。

输入
map.txt: alice dev\nbob ops\ndata.txt: alice 30\nbob 28
输出
alice 30 dev
bob 28 ops
例子
awk 'NR==FNR{a[$1]=$2;next} {print $0, a[$1]}' users.tsv logins.tsv
awk '!seen[$0]++' file

保序去重(不像 sort -u 会乱序)。`seen[$0]++` 首次返回 0(假,取反为真,打)。

输入
a
b
a
c
b
d
输出
a
b
c
d
例子
awk '!seen[$0]++' urls.txt
awk '{ s+=$3 } END { print s/NR }' file

算第三列均值,累加除以 NR。只算非空行用 `NF { s+=$3; n++ } END { print s/n }`。

输入
a 1 10
b 2 20
c 3 30
输出
20
例子
awk '{ s+=$3 } END { print s/NR }' scores.txt
awk 'BEGIN { max=-1 } $2>max { max=$2; line=$0 } END { print line }' file

找第二列最大值所在行。流式 max,单遍 O(1) 内存。

输入
a 10
b 50
c 30
输出
b 50
例子
awk 'BEGIN{m=-1} $2>m{m=$2;line=$0} END{print line}' scores.txt
awk '{ n=split($0, parts, "/"); print parts[n] }' file

split() 把字符串切到数组里。这里取每个 / 分隔的路径的最后一段(basename)。

输入
/a/b/c.txt
/x/y
输出
c.txt
y
例子
awk '{ n=split($0,p,"/"); print p[n] }' paths.txt
awk '{ gsub(/[0-9]+/, "N") } 1' file

gsub() = 全局替换。把所有数字串换成 N。末尾的 1 触发默认打印。

输入
order 42 then 1337
输出
order N then N
例子
awk '{ gsub(/secret-[a-z0-9]+/, "[REDACTED]") } 1' file
awk '{ print substr($0, 1, 80) }' file

把每行截到 80 字符。substr(字符串, 起始, 长度),起始从 1 开始。

例子
awk '{ print substr($0, 1, 80) }' wide.log
awk '{ print toupper($0) }' file

整行转大写。配套有 tolower()。

输入
hello
world
输出
HELLO
WORLD
例子
awk '{ print toupper($1), tolower($2) }' data.txt
awk -F'\t' 'BEGIN { OFS="," } { $1=$1; print }' in.tsv

一行把 TSV 转成 CSV。Tab 作输入 FS,逗号作输出 OFS,$1=$1 触发重写。

例子
awk -F'\t' 'BEGIN{OFS=","} {$1=$1;print}' in.tsv > out.csv
awk 'length > 80' file

只打长度超过 80 的行。length 不带参数返回 $0 的长度。

例子
awk 'length > 120' src/**/*.py   # find long lines
awk 'BEGIN { RS=""; FS="\n" } { print $1 }' file

段落模式:RS 设空串后,awk 按空行分隔的块当一条记录。$1 是每段第一行。

例子
awk 'BEGIN { RS=""; FS="\n" } { print $1 }' essay.txt
awk -F: '$3 >= 1000 { print $1 }' /etc/passwd

只列真人用户,UID 列 ≥ 1000。冒号分隔,条件写在 { 动作 } 前。

例子
awk -F: '$3 >= 1000 && $7 != "/usr/sbin/nologin" { print $1 }' /etc/passwd
awk '{ sum[$1] += $2 } END { for (k in sum) print k, sum[k] }' file

分组求和:按第一字段分组,对第二字段求和。聚合数据时关联数组的主力写法。

输入
a 10
b 5
a 20
b 7
输出
a 30
b 12
例子
awk '{rev[$1]+=$3} END{for(k in rev)print k,rev[k]}' sales.txt
awk 'BEGIN{min=1e9;max=-1e9} {if($1<min)min=$1; if($1>max)max=$1; s+=$1; n++} END{print "min",min,"max",max,"avg",s/n}' file

一遍算出第一列的最小值、最大值、平均值。min 设很大、max 设很小,逐个折进去。

输入
5
2
9
4
输出
min 2 max 9 avg 5
例子
awk '{s+=$1;n++} END{print s/n}' nums.txt   # just the mean
awk 'seen[$2]++ == 0' file

每个第二列不同值只留首次出现的那行(按 key 列保序去重)。

输入
a x
b x
c y
d y
输出
a x
c y
例子
awk '!seen[$1]++' file   # dedupe by first column
awk 'END { print NR, NF }' file

打总行数和最后一行的字段数,快速看一张表的形状。

输入
a b c
d e f
输出
2 3
例子
awk -F, 'END{print NR" rows, "NF" cols"}' data.csv
awk 'p { print p } { p=$0 }' file

靠缓存前一行,打除最后一行外的所有行。`p` 存上一条记录,最后一条永远没轮到打。

输入
a
b
c
d
输出
a
b
c
例子
awk 'NR>1{print prev} {prev=$0}' file   # same idea, named var
awk '{ a[NR]=$0 } END { for (i=NR;i>=1;i--) print a[i] }' file

把每行按 NR 存进数组,再从后往前打,实现整文件反转。awk 版 tac。

输入
1
2
3
输出
3
2
1
例子
awk '{a[NR]=$0} END{for(i=NR;i;i--)print a[i]}' file
awk 'BEGIN{FS=OFS=","} {$2=toupper($2)}1' file.csv

原地改一列 CSV:把第 2 字段转大写并重打整行。FS=OFS 一起设保持逗号格式。

输入
a,b,c
d,e,f
输出
a,B,c
d,E,f
例子
awk 'BEGIN{FS=OFS=","}{$3=$3*1.1}1' prices.csv   # bump column 3 by 10%
awk 'match($0, /[0-9]+/) { print substr($0, RSTART, RLENGTH) }' file

抽出每行第一个数字。match() 设置 RSTART 和 RLENGTH,再用 substr() 切出来。

输入
order 42 total
item 7
输出
42
7
例子
awk 'match($0,/[A-Z]{3,}/){print substr($0,RSTART,RLENGTH)}' file
awk 'NF { $1=$1; print } !NF { print }' file

把非空行的内部空白规整(用 $1=$1 重建压掉多余 FS),空行保持原样。

输入
a   b   c

x  y
输出
a b c

x y
例子
awk '{$1=$1}1' file   # squeeze whitespace everywhere
awk '{ for(i=NF;i>=1;i--) printf "%s%s", $i, (i>1?OFS:ORS) }' file

把每行的字段顺序反转,从第 NF 个打到第 1 个,用 OFS 连接。

输入
a b c
输出
c b a
例子
awk '{for(i=NF;i>=1;i--)printf "%s%s",$i,(i>1?" ":"\n")}' file
awk '/start/{f=1} f; /end/{f=0}' file

用标志变量打标记之间的块,比范围地址灵活,你能控制标记本身是否打印。

输入
x
start
A
end
y
输出
start
A
end
例子
awk '/BEGIN/{f=1;next} /END/{f=0} f' file   # exclude both markers
awk '{ print > ("part_" int((NR-1)/100) ".txt") }' file

把文件按每 100 行切块,给每条记录算出文件名并重定向 print(awk 版 split)。

例子
awk '{print > ("chunk_" int(NR/1000) ".txt")}' big.log
awk · 一行命令 (24)
awk '{ s += $1 } END { print s }' file

第一列求和。awk 处理数字最经典的一条。

输入
10
20
30
输出
60
例子
awk '{s+=$1} END {print s}' nums.txt
awk -F, 'NR>1 { s += $3 } END { print s }' data.csv

对 CSV 第三列求和,跳过表头那一行。

例子
awk -F, 'NR>1 {s+=$3} END {print s}' sales.csv
awk '{ print $3, $2, $1 }' file

调列序:打第 3、第 2、第 1 列。

输入
a b c
1 2 3
输出
c b a
3 2 1
例子
awk '{print $NF, $1}' file   # last column, then first
awk '{ print $1, $3 }' file

挑指定列(第 1 和第 3)。配 -F 就是支持正则的 cut。

例子
awk -F, '{ print $1, $3 }' data.csv
ps aux | awk '$3 > 50 { print $2, $11 }'

找 CPU 占用 >50% 的进程,打 PID 和命令。真实管道用法。

例子
ps aux | awk '$3 > 50 {print $2, $11}'
df -h | awk '$5+0 > 80 {print $0}'   # disks >80% full
awk '{ print length, $0 }' file | sort -n

按长度排行(从短到长)。awk 配 sort 的常见组合。

例子
awk '{print length, $0}' words.txt | sort -n | head
awk '{ c[$1]++ } END { for (k in c) print c[k], k }' file | sort -rn

分组计数 + 按次数倒排,一行就出 top-N。

例子
awk '{c[$1]++} END {for(k in c)print c[k],k}' access.log | sort -rn | head
awk 'NR % 2 == 0' file

打偶数行(2、4、6 …)。`% 2 == 1` 打奇数行。

输入
a
b
c
d
输出
b
d
例子
awk 'NR%2==1' interleaved.txt   # odd lines
awk '{ print } /pattern/ { c++ } END { print c " matches" }' file

一边打文件,一边数 /pattern/ 命中,结尾报总数。两个动作走一遍。

例子
awk '{print} /ERROR/{c++} END{print c, "errors"}' app.log
awk 'BEGIN { srand(); for(i=0;i<5;i++) print int(rand()*100) }'

在 [0, 100) 之间生成 5 个随机整数。BEGIN 里一定要 srand(),不然 awk 用固定种子。

例子
awk 'BEGIN{srand();for(i=0;i<10;i++)print int(rand()*1000)}'
awk -F: '{ print NR": "$1 }' /etc/passwd

列用户名带行号,冒号分隔文件的快速 nl 替代。

例子
awk -F: '{print NR": "$1}' /etc/passwd
awk -F, 'END { print NF }' file.csv

读最后一行的 NF 数 CSV 列数。快速看"这个 CSV 多宽"。

例子
awk -F, 'END {print NF}' wide.csv
awk 'END { print NR }' file

数行数,像 wc -l,但没有某些 wc 会加的前导空格。

输入
a
b
c
d
输出
4
例子
awk 'END{print NR}' file
awk '{ w += NF } END { print w }' file

把每行的 NF 加起来,数全文单词总数,awk 版 wc -w。

输入
one two
three
输出
3
例子
awk '{w+=NF} END{print w}' essay.txt
awk '{ print $NF }' file

只打每行最后一个字段,挑文件名、状态码或末尾值很方便。

输入
GET /a 200
POST /b 404
输出
200
404
例子
awk '{print $(NF-1)}' file   # second-to-last field
awk 'NR==1 { print; exit }' file

只打第一行就立刻 exit,高效的 head -1,读到第一行就停。

输入
a
b
c
输出
a
例子
awk 'NR==1{print;exit}' huge.csv   # grab the header fast
awk -F, '{ print NF }' file.csv | sort -u

列出 CSV 各行的不同列数,快速发现列数不齐的行。

例子
awk -F, '{print NF}' data.csv | sort | uniq -c
awk '$0 ~ /foo/ { c++ } END { print c+0 }' file

数匹配 /foo/ 的行(grep -c)。`+0` 在没匹配时强制输出数字 0 而不是空串。

输入
foo
bar
foo
输出
2
例子
awk '/ERROR/{c++} END{print c+0}' app.log
awk '{ print rand(), $0 }' file | sort -n | cut -d' ' -f2-

给每行贴随机数、排序、再去掉标记来打乱行序,可移植的 shuf 替代。

例子
awk 'BEGIN{srand()}{print rand(),$0}' file | sort -n | cut -d' ' -f2-
awk 'NR==FNR{n++;next} FNR==int(n*0.5)' file file

读两遍文件打中位行:第一遍数行数,第二遍打中间那行。

例子
awk 'NR==FNR{n++;next} FNR==int((n+1)/2)' file file
awk '{ gsub(/^ +| +$/, "") } 1' file

一个 gsub 去掉每行首尾空格(`^ +` 和 ` +$` 取或),再默认打印。

输入
   hi   
  bye
输出
hi
bye
例子
awk '{gsub(/^[ \t]+|[ \t]+$/,"")}1' file   # also tabs
awk -F, '{ print $1 }' file | sort | uniq -c | sort -rn

按频次排 CSV 第一列的高频值:抽列、计数、倒排。经典日志分析管道。

例子
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head
awk 'BEGIN { for(i=1;i<=10;i++) print i }'

不要输入文件,生成 1 到 10 的数字,awk 版 seq。

输出
1
2
3
4
5
6
7
8
9
10
例子
awk 'BEGIN{for(i=0;i<=100;i+=5)print i}'   # 0,5,10,...,100
awk '{ t = $1; $1 = $NF; $NF = t; print }' file

用临时变量交换每行的首字段和末字段,再默认重建打印。

输入
a b c
1 2 3
输出
c b a
3 2 1
例子
awk '{t=$1;$1=$NF;$NF=t;print}' file
awk · 常见坑 (10)
Floating-point precision (IEEE 754)

awk 数字是 C double。`awk "BEGIN{print 0.1+0.2}"` 打出 0.3 是被默认 OFMT 圆掉了,`printf "%.17f\n", 0.1+0.2` 才看见真相 0.30000000000000004。

常见坑: 浮点别用 == 比较。求和后用容差比:`if (s > target - 0.001 && s < target + 0.001)`。算钱用整数(分),最后再除回元。

例子
awk 'BEGIN { printf "%.17f\n", 0.1+0.2 }'   # 0.30000000000000004
awk 'BEGIN { OFMT="%.10g"; print 0.1+0.2 }'
OFS does not auto-apply

光设 OFS 没用,至少改一个字段才会生效。不动字段输出原样不变。

常见坑: 标准修复:`$1=$1` 空操作触发 OFS 重写。`awk "BEGIN{OFS=\",\"}{$1=$1;print}"`。

例子
awk 'BEGIN{OFS=","}{$1=$1;print}' file
NR vs FNR with multiple files

NR 跨文件累加,FNR 每个文件重置。`NR==FNR` 等价"还在读第一个文件",双文件 join 的经典写法。

例子
awk 'NR==FNR{a[$1]=$2;next} {print $0, a[$1]}' map.txt data.txt
Numeric strings sort lexically without +0

awk 按上下文决定字段是字符串还是数字。要强制按数字比较(尤其排序场景),加个 0:`$3+0 > 100`。

常见坑: `awk "$3 > 100" data.txt` 在第三列像数字时没问题,但行里有 "42MB" 这样的会悄悄走字符串比较,结果误导你。

例子
df -h | awk '$5+0 > 80'   # force numeric on "80%"
gawk vs awk vs mawk

常见三种 awk:gawk(GNU)功能最全(真正则、--csv、网络),mawk 最快,macOS 自带 BSD awk 最弱。

常见坑: gawk 上能跑的 `gsub(/regex/, "x", arr[i])`,BSD awk 不行;用 `length(array)` 的脚本需要 gawk。`awk --version` 确认手里是哪一只。

例子
awk --version 2>&1 | head -1
brew install gawk   # macOS users wanting gawk
Uninitialized variables are 0 and empty

awk 没初始化的变量既是数字 0 又是空串,按上下文决定。计数器很方便,但变量名打错也会被悄悄当成 0。

常见坑: 把计数器名打成 `coutn[$1]++`,awk 照样新建一个数组,不报错,只给你错答案。除非 `gawk --lint`,否则没有"变量未定义"警告。

例子
gawk --lint '{c[$1]++} END{for(k in c)print k,c[k]}' file
print vs printf newline

`print` 会补 ORS(默认换行);`printf` 什么都不补,得自己写 `\n`,否则输出会连成一团。

常见坑: `awk "{printf \$1}"` 把每个第一字段无分隔地粘成一长行。补换行:`printf "%s\n", $1`。

例子
awk '{printf "%s\n", $1}' file   # remember the \n
-F with a regex vs a literal

单字符 -F 按字面;多字符 -F 值当正则。所以 `-F.` 是按任意字符切,不是按字面点号。

常见坑: `awk -F. "{print \$1}"` 处理 `a.b.c` 打出空字段,因为 `.` 是正则"任意字符"。转义它:`-F"\\."` 或 `-F"[.]"`。

例子
awk -F'[.]' '{print $1}' host.example.com   # split on literal dot
Leading-zero numbers and octal

像 "010" 这样的字段值在算术里当十进制 10,但前导零和进制相关的字符串与数字转换会让你意外,尤其用 strtonum() 时。

常见坑: gawk `strtonum("010")` 返回 8(八进制),而 `"010"+0` 返回 10。在同一份数据上混用结果不一致。选定一种转换方式并贯彻到底。

例子
awk 'BEGIN{print "010"+0}'   # 10
gawk 'BEGIN{print strtonum("010")}'   # 8
Modifying $0 resplits the fields

给 $0 赋值会用当前 FS 重新分字段,给任一字段赋值会用 OFS 重建 $0。顺序没留意时两者会互相覆盖。

常见坑: 若写 `$0 = $0 "x"; print $3`,字段会从新的 $0 重新计算,之前对字段的修改可能丢失。整体改 $0 之前先把字段编辑做完。

例子
awk '{$0=$0" extra"; print NF}' file   # NF recomputed

这个工具能做什么

可搜索的 awk + sed 速查,80+ 条一行命令,覆盖你周二早上真正 会在 shell 里敲的文本处理任务。每个工具分四类。sed 基础: s/// 替换、全局 g、第 N 次匹配的数字 flag、地址范围、d 删除、 p 打印(配 -n)、i 插入、a 追加、c 替换、y 字符转换。sed 高级: hold space(h H g G x)、pattern space 技巧、分支跳转、多文件 改、GNU sed 与 BSD sed 的 -i 差异、macOS 上 -i 后那个空 '' 的坑、in-place 备份、BRE vs ERE 正则。awk 基础:NF NR $0 $1 $2、BEGIN 和 END 块、printf 格式串、FS / OFS / RS / ORS、 pattern { action } 流程、/regex/、范围模式、-F 字段分隔、-v。 awk 进阶:关联数组、split()、substr()、gsub()、length()、 toupper/tolower()、累加模式(求和/均值/max/min)、用数组去 重、FNR==NR 双文件 join、输出格式化、配合 sort / uniq / grep 接管道。日常一行命令:删空行、删第 N 行或末行、只打第 10 到 20 行、只在匹配行里替换、列求和、列求均值、统计去 重、交换两列、从 CSV 取第三列、保序去重。再加"常见坑"一节: GNU sed 和 BSD sed 的 -i 不一样,macOS 上要 sed -i '' 加个空 字符串;awk 浮点是 double,0.1+0.2 出来是 0.30000000000000004; 正则方言(BRE vs ERE)把 perl 来的人坑哭;sed URL 里斜杠撞, 要换分隔符(s|http://||);awk 的 OFS 不重新赋值字段就不 生效。每条都给中英文双语说明、真实输入输出、对应坑、至少 一条能直接拷贝的例子。搜索框跨命令/说明/坑/输入输出/例子 五个字段一起过滤,工具胶囊切 awk / sed,分类胶囊切 基础 / 高级 / 一行命令 / 常见坑,每条一键复制。完全浏览器里跑, 不上传不追踪。

工具细节

输入
文本
页面会根据工具类型展示文本框、数值控件、文件选择或结构化输入。
输出
即时结果 + 复制
结果区优先给出可操作结果,支持项会显示复制、下载或可视化预览。
隐私
浏览器本地处理
主工具逻辑未发现外部 API 调用,输入通常留在当前标签页内处理。
保存 / 分享
可分享链接状态
关键设置会进入 URL,复制链接后别人能复现同一组参数。
性能预算
首屏 JS ≤ 25 KB
没有声明 WASM 依赖,适合快速打开和移动端使用。
适用场景
开发运维 · 程序员
分类和职业标签用于推荐相关工具、组织内链,并帮助用户快速判断是否适合当前任务。

怎么用

  1. 1. 输入

    把内容粘贴或拖入工具面板。

  2. 2. 处理

    点击按钮,在浏览器内本地处理,文件不上传。

  3. 3. 复制 / 下载

    一键复制结果或下载到本地。

awk + sed 命令速查 适合怎么用

适合穿插在写代码、查问题、做 Review、上线前的小任务里。

适合开发场景

  • 格式化、校验、压缩或检查和代码相关的文本。
  • 把片段整理好再放进文档、工单、提交或交接材料。
  • 不切换工具,快速检查一个小 payload。

开发检查项

  • 压缩、混淆这类不可逆处理,先对副本操作。
  • 除非确认工具本地处理,不要粘贴密钥和敏感片段。
  • 转换后的代码上线前,仍要跑自己的测试或 lint。

下一步可以接着做

这些入口会把当前任务接到更完整的工具链里。

  1. 1 Nginx 速查表 Nginx 速查表,常见配置、location/server 块、SSL、反代、gzip,真实例子和常见坑。 打开
  2. 2 curl 命令速查 curl 命令速查,80+ 条覆盖 GET/POST/认证/上传/下载/SSL/代理,真实例子和常见坑。 打开
  3. 3 Vim 速查表 Vim 速查表,100+ 条命令含模式、移动、编辑、搜索、寄存器、分屏,带记忆法。 打开

真实使用场景

  • 发版冻结前把一个函数名改遍 300 个文件

    团队把 `getUser` 改名成 `fetchUser`,CI 在 312 个源文件上飘红。你先用 `rg -l 'getUser' | xargs sed 's/getUser/fetchUser/g'` 不带 -i 跑一遍配 diff 预览,确认无误再原地替换。速查里的多文件 sed 那条加 macOS `-i ''` 的坑,帮你躲掉那个会把半个改名悄悄漏掉的静默空操作。

  • 在跳板机上数一份 2 GB 访问日志里的 HTTP 状态码

    线上一直冒 500,你只有一台离网机器的 shell,没 Python 没外网。拷一条 分组命令 `awk '{ c[$9]++ } END { for (k in c) print k, c[k] }' access.log`, 4 秒钟就看出 503 从 12 次飙到 8400 次。关联数组那条恰好是你凭记忆 写不出来的模式。

  • 给季度财报从乱糟糟的 CSV 里取第三列

    供应商甩来一份 5 万行的 CSV,季度结账要把第三列求和。你抓 `awk -F, '{ s += $3 } END { print s }' data.csv`,撞上 FAQ 提醒的 带引号逗号那个坑,换成 `gawk --csv`。速查在有人签字之前就把你从 一个错误总数边上绕开了。

  • 对比两台服务器配置前先去掉空行和注释

    两台 nginx 机器漂移,配置只差空白和注释。你用 `awk 'NF && $1 !~ /^#/' a.conf` 和 `... b.conf` 把两边都归一化再 diff。四个字符的 `awk 'NF'` 写法把一份 400 行的吵闹 diff 收成真正改了的那三行。

常见踩坑

  • macOS 上忘了那对空引号。`sed -i 's/a/b/' f` 在 BSD sed 上啥也不干,要写 `sed -i '' 's/a/b/' f` 或可移植的 `sed -i.bak '...'`。

  • 拿 `awk -F,` 硬怼真实 CSV。`"Smith, John"` 这种字段会被里面的逗号切开。引号里可能含逗号时,换 `gawk --csv`(gawk 5.3+)或 `mlr`。

  • 以为 OFS 会自己重排输出。`awk '{ OFS="," } 1'` 还是原来的空格,得碰一下字段,比如 `awk '{ $1=$1 } 1'`,才会触发重建。

隐私说明

每条一行命令、搜索框、awk/sed 与分类胶囊、复制按钮全在你浏览器里跑,对着 一个内存里的数组。你敲的命令、搜的词、拷的内容都不会发到服务器,也不会写 进分享链接的 URL。打开 DevTools 的 Network 一边输入一边看,零出站请求。 公司代理后面、飞机上、离网跳板机上都照跑,而这些场景恰恰最需要 awk 和 sed。

常见问题

类似工具组合

做你这行的人, 还会一起用这些。

Made by Toolora · 100% client-side · Updated 2026-06-13