Skip to main content

19.awk的使用

1 什么是awk?

awk是一门文本处理语言,其作用是对文本匹配,过滤,统计和基本的逻辑运算,最后文本中的过滤后或统计后的 结果。awk于1977年在贝尔实验室被创造出来,其命名取自 Alfred Aho, Peter WeinbergerBrian Kernighan 这三位 创始人的名称首字母。

2 直观的使用示例

只展示文本的第一列信息

$ netstat -tulpen | awk '{print $1}'
Active
Proto
tcp
tcp
tcp6
udp
udp
udp
udp
udp6
udp6

3 awk在线测试工具

https://awk.js.org/

4 流程控制

4.1 if 流程

以下示例意图为:判断第二列的参数是否为algolia/docsearch-scraper, 如果是则输出第一列

找出第一列名为algolia/docsearch-scraper的镜像
$docker images | awk '{ \
if ($1 == "algolia/docsearch-scraper") { \
print \
} \
}'
输出
algolia/docsearch-scraper   latest                   04e04eaa5c7d   5 months ago   1.74GB

5 正则匹配

5.1 正向匹配

awk的正则用法
$ awk'[column] ~ [regex] {print [column]}'

比如有一个场景, git中有一些忽略文件被添加到暂存区,由于数据很多,手动找太麻烦了,这时就可以使用正则的方式把这些都找出来:

$ git status
On branch master

No commits yet

Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: .gitignore
new file: .idea/.gitignore
new file: .idea/misc.xml
new file: .idea/modules.xml
new file: .idea/observe.iml
new file: .idea/vcs.xml
new file: jest.config.js
new file: lib/SubscriptionService.ts
new file: lib/SubscriptionServiceI.ts
new file: lib/useObserve.ts
new file: package.json
new file: test/index.test.tsx
new file: tsconfig.json
new file: tslint.json
new file: yarn.lock
$ git status | awk '$3 ~ /\.idea/ {print $3}' # <-- 通过 awk'[column] ~ [regex] {print [column]}'
.idea/.gitignore
.idea/misc.xml
.idea/modules.xml
.idea/observe.iml
.idea/vcs.xml
tip

以上是只把需要的文件找出来了,但有多行,需要转换为一行才能当成git的参数使用;所以可以用tr把换行符替换成空格,如:

tr把多行参数输入转换成单行输出
$ git status | awk '$3 ~ /\.idea/ {print $3}' | tr '\n' ' '
.idea/.gitignore .idea/misc.xml .idea/modules.xml .idea/observe.iml .idea/vcs.xml %    ~/Desktop/myprojects/a1001-zhuche/observe  on   master +15   ✔  at 17:21:40 

然后直接当成git的删除暂存区参数,就可以直接删除这些文件了

$ git rm --cached $(git status | awk '$3 ~ /\.idea/ {print $3}' | tr '\n' ' ' )
$ git status
rm '.idea/.gitignore'
rm '.idea/misc.xml'
rm '.idea/modules.xml'
rm '.idea/observe.iml'
rm '.idea/vcs.xml'

5.2 反向匹配

awk的正则用法
$ awk'[column] !~ [regex] {print [column]}'

$ git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
deleted: .idea/.gitignore
deleted: .idea/inspectionProfiles/Project_Default.xml
deleted: .idea/modules.xml
deleted: .idea/pnote-app.iml
deleted: .idea/vcs.xml
modified: package.json
modified: src/index.ts
renamed: src/windows/mainWindow/createMainWindow.ts -> src/mainProcess/windows/mainWindow/createMainWindow.ts
renamed: src/windows/mainWindow/events/windowMaximizeToggleEvent.ts -> src/mainProcess/windows/mainWindow/events/windowMaximizeToggleEvent.ts
renamed: src/windows/mainWindow/preload.ts -> src/mainProcess/windows/mainWindow/preload.ts
deleted: yarn.lock

如以上中需要找出不是.idea开头的文件,且是第3行开始的,则awk表达式`为:

$  g status | awk 'NR > 3 && $2 !~ /ide/ {print $2}'
package.json
src/index.ts
src/windows/mainWindow/createMainWindow.ts
src/windows/mainWindow/events/windowMaximizeToggleEvent.ts
src/windows/mainWindow/preload.ts
yarn.lock

6 内置变量

变量说明示例
NF最后一列如: 打印最后一列, $ awk '{print $(NF)}'
NR当前行号如:选择等号大于1的数据, awk 'NR > 1 {print $1}', 注意: 默认行号是从1开始的

7 正则匹配

示例样本
demoTxt=$( cat <<EOF
vim/cocvim/coc/extensions/package.json
vim/cocvim/config/coc-settings.json
vim/cocvim/config/init.lua
vim/cocvim/config/lua/plugin-configs/coc/init.lua
vim/cocvim/config/lua/plugin-configs/telescope.lua
vim/cocvim/config/lua/plugins.lua
vim/cocvim/config/plugin/packer_compiled.lua
vim/cocvim/config/coc-extensions/
EOF
)

7.1 匹配运算符 ~

匹配行中有init.luacoc-extensions关键词的行。

$ echo $demoTxt | awk '$0 ~ "coc-extensions|init.lua" {print $0}'
vim/cocvim/config/init.lua
vim/cocvim/config/lua/plugin-configs/coc/init.lua
vim/cocvim/config/coc-extensions/

7.2 不匹配运算符!~

不匹配行中有init.luacoc-extensions关键词的行。

$ echo $demoTxt | awk '$0 !~ "coc-extensions|init.lua" {print $0}'
vim/cocvim/coc/extensions/package.json
vim/cocvim/config/coc-settings.json
vim/cocvim/config/lua/plugin-configs/telescope.lua
vim/cocvim/config/lua/plugins.lua
vim/cocvim/config/plugin/packer_compiled.lua