シェル システム プログラミングの三銃士 - AWK

目次

1: AWK の概要

1. AWK ツールの概要

2. AWKの基本フォーマット

3. AWKの動作原理

4. 共通の組み込み変数(直接使用可能)

2: AWK の例

1. テキストを行ごとに出力する

2. フィールドごとにテキストを出力する

 3. パイプと二重引用符を使用してシェル コマンドを呼び出します。

 4.dateコマンド出力時刻

5. メモリ使用率を表示する

6. CPU使用率を確認する

7. 奇数行と偶数行を取得する

8.OFS出力セパレータ

 9. アレイ

10. 重複チェック

 11. フィルターパスワードが失敗しました


1: AWK の概要

1. AWK ツールの概要

●AWK は、テキスト ファイルを処理するための言語です。強力なテキスト分析ツールです。テキスト処理用に特別に設計されたプログラミング言語です。また、通常、スキャン、フィルタリング、統計集計に使用される行処理ソフトウェアでもあります。

●複雑なテキスト操作を非対話モードで実装でき、データは標準入力、パイプ、またはファイルから取得できます。

●通常、行全体で動作する sed と比較して、awk は小さなテキスト データに非常に適しているため、行を複数のフィールドに分割して処理する傾向があります。

2. AWKの基本フォーマット

1.awk [选项] ‘模式条件{操作}’ 文件1 文件2…
2.awk -f 脚本文件 文件1 文件2…
格式:awk关键字 选项 命令部分 ‘{xxx}’ 文件名

3. AWKの動作原理

● 前述したように、sed コマンドは行全体を処理するためによく使用されますが、awk は行を複数の「フィールド」に分割して処理することを好み、デフォルトではフィールド区切り文字はスペースまたはタブ キーです。awkの実行結果はprint関数によりフィールドデータを印刷表示することができます。

●awkコマンドを使用する過程では、論理演算子「&&」で「and」を、「||」で「or」を、「!」で「 not」を表すことができ、簡単な算術演算も可能です。 +、-、*、/、%、^ などの演算は、それぞれ加算、減算、乗算、除算、剰余、累乗を表します。

● awk の後には2 つの一重引用符と中括弧 { } が続き、データに対して実行する処理操作を設定します。awk は後続のファイルを処理でき、前のコマンドからの標準出力を読み取ることもできます。

4. 共通の組み込み変数(直接使用可能)

変数 意味
FS 列分割符テキストの各行のフィールド区切り文字を指定します。デフォルトは です空格或制表位「-F」と同じ
NF 現在処理中です行的字段个数
NR 現在処理中です行的行号(序数)
$0 現在処理中です行的整行内容
1ドル 代表する第一列的内容
2ドル 2 番目の列の内容を表します
$n 現在処理されている行の n 番目のフィールド
ファイル名 処理されるファイル名。
RS 行区切り文字

注: awk がファイルからデータを読み取るとき、RS の定義に従ってデータが多数のレコードに分割され、awk は一度に 1 つのレコードのみを読み取って処理します。デフォルト値は '\n' です
。つまり、データ レコードは分割されており、デフォルトは \n です。つまり、各行に 1 つのレコードがあります。

2: AWK の例

1. テキストを行ごとに出力する

#输出所有内容
[root@localhost ~]# awk '{print}' a
[root@localhost ~]# awk '{print $0}' a

#输出1-3行的内容
[root@localhost ~]# awk 'NR==1,NR==3{print}' a
[root@localhost ~]# awk '(NR>=1)&&(NR<=3){print}' a

#输出第一行或第三行
[root@localhost ~]# awk 'NR==1||NR==3{print}' a

#输出4-8行,或10行
[root@localhost ~]# awk '(NR>=4&&NR<=8)||NR==10 {print $0}' a
four
five
six
seven
eight
ten

[root@localhost ~]# awk '(NR%2)==1{print}' a    #输出所有奇数行
[root@localhost ~]# awk '(NR%2)==0{print}' a    #输出所有偶数行

#配合正则表达式使用输出
[root@localhost ~]# awk '/^root/{print}' /etc/passwd        #输出以root开头的行
[root@localhost ~]# awk '/nologin$/{print}' /etc/passwd     #输出以 nologin 结尾的行
[root@localhost ~]# awk 'NR!=10 {print $0}' a               #输出不是第10行的所有行

#统计以nologin为结尾的行数
[root@localhost ~]# grep -c "nologin$" /etc/passwd
[root@localhost ~]# awk '/nologin$/ {print $0}' /etc/passwd | wc -l
[root@localhost ~]# awk 'BEGIN {x=0}; /nologin$/ {x++}; END {print x}' /etc/passwd
[root@localhost ~]# awk 'BEGIN {x=0}; /nologin$/ {x++; print x, $0}; END {print x}' /etc/passwd

注: BEGIN モードは、指定されたテキストを処理する前に、BEGIN モードで指定されたアクションを実行する必要があることを意味します。awk は、指定されたテキストを処理してから、END モードで指定されたアクションを実行します。END {} ステートメント ブロックでは、結果の印刷などの Enter ステートメントが配置されることが多い 

2. フィールドごとにテキストを出力する

#输出以root开头的行的第一部分
[root@localhost ~]# awk -F: '/^root/ {print $1}' /etc/passwd

#输出以root开头的行的第一部分和第三部分
[root@localhost ~]# awk -F: '/^root/ {print $1,$3}' /etc/passwd

#输出以root开头的行的第一部分和第三部分,最后一部分
[root@localhost ~]# awk -F: '/^root/ {print $1,$3,$NF}' /etc/passwd

#输出第三部分不小于200的行
[root@localhost ~]# awk -F ":" '!($3<200){print}' /etc/passwd 

#以冒号为分隔符,第三部分大于等于1000。先处理完BEGIN的内容,再打印文本里面的内容
[root@localhost ~]# awk 'BEGIN {FS=":"};{if($3>=1000){print}}' /etc/passwd

#!表示为取反
[root@localhost ~]# awk -F: '!($3>8) {print $3,$1}' /etc/passwd
[root@localhost ~]# awk -F: 'BENGIN {FS=":"}; !($3>8) {print $3,$1}' /etc/passwd

#($3>$4)?$3:$4;三元运算符,如果第3个字段的值大于等于第4个字段的值,则把第3个字段的值赋给max,否则第4个字段的值赋给max
[root@localhost ~]# awk 'BEGIN {FS=":"};{if($3>=1000){print}}' /etc/passwd

#输出以冒号分隔且第7个字段中包含/bash的行的第1个字段,~意思为包含
[root@localhost ~]# awk -F ":" '$7~"/bash"{print $1}' /etc/passwd

#输出第1个字段中包含root且有7个字段的行的第1、2个字段
[root@localhost ~]# awk -F ":" '($1~"root")&&(NF==7){print $1,$2}' /etc/passwd

#输出第7个字段既不为/bin/bash,也不为/sbin/nologin的所有行
[root@localhost ~]# awk -F ":" '($7!="/bin/bash")&&($7!="/sbin/nologin"){print}' /etc/passwd

 3. パイプと二重引用符を使用してシェル コマンドを呼び出します。

#输出行号和内容
[root@localhost ~]# awk '{print NR,$0}' a

#输出行号和内容
[root@localhost ~]# awk '{print NR,$0};END{print NR}' a

#以冒号为分隔符,输出内容和行号
[root@localhost ~]# echo $PATH | awk 'BEGIN{RS=":"}; {print NR,$0}'

#调用w命令,并用来统计在线用户数
[root@localhost ~]# awk 'BEGIN {n=0 ; while ("w" | getline) n++ ; {print n-2}}'

#查询用户名
[root@localhost ~]# awk 'BEGIN {"hostname" | getline ; {print $0}}'

 4.dateコマンド出力時刻

[root@localhost ~]# date -d "1 month" +"%Y/%m/%d"          #下个月的今天
[root@localhost ~]# date -d "1 month" +"%Y/%m/01"          #下个月第一天
[root@localhost ~]# date +"%Y/%m/01"                       #当月第一天
[root@localhost ~]# date -d "1 month ago" +"%Y/%m/%d"      #一个月前的今天
[root@localhost ~]# date -d "1 day ago" +"%Y/%m/%d"        #1天前
[root@localhost ~]# date -d "-1 day " +"%Y/%m/%d"          #1天前
[root@localhost ~]# date -d "$(date +%Y%m01) -1 day" +%Y/%m/%d    #上个月的最后一天
[root@localhost ~]# date -d "$(date -d "1 month" +%Y%m01) -1 day" +%Y/%m/%d  #当月最后一天

[root@localhost ~]# date -d "$(cat /proc/uptime | awk -F. '{print $1}') second ago" +"%Y%m%d %H:%M:%S"         
#显示上次系统重启时间,等同于uptime;second ago为显示多少秒前的时间,+"%F %H:%M:%S"等同于+"%Y-%m-%d %H:%M:%S"的时间格式
/proc/uptime 第一列输出的是,系统启动到现在的时间(以秒为单位);第二列输出的是,系统空闲的时间(以秒为单位)
date -d "$(date -d"1 month" +"%Y%m01") -3 day" +"%Y%m%d"  当月倒数第三天
date +"%Y%m01"        当月第一天

5. メモリ使用率を表示する

#内存使用率占比
[root@localhost ~]# free -m | awk '/Mem/ {print $3/$2 * 100"%"}

#内存空闲率占比
[root@localhost ~]# free -m | awk '/Mem/ {print ($2-$3)/$2 * 100"%"}'

6. CPU使用率を確認する

#cpu使用率占比
[root@localhost ~]# top -b -n1 | awk -F, '/%Cpu/ {print $4}' | awk '{print 100-$1"%"}'

7. 奇数行と偶数行を取得する

[root@localhost ~]# seq 10 | awk '{getline; print $0}'    #获取偶数行
[root@localhost ~]# seq 10 | awk '{print $0; getline}'    #获取奇数行
当getline左右无重定向符“<”或“|”时,awk首先读取到了第一行,就是1,然后getline,就得到了1下面的第二行,就是2,因为getline之后,awk会改变对应的NF,NR,FNR和$0等内部变量,所以此时的$0的值就不再是1,而是2了,然后将它打印出来。
当getline左右有重定向符“<”或“|”时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。

 8.OFS出力セパレータ

#OFS为指定分隔符
[root@localhost ~]# echo "A B C D" | awk '{OFS="|";print $0;$1=$1;print $0}'               
#以|为分隔符输出
[root@localhost ~]# echo "A B C D" | awk '{OFS="/";print $0;$1=$1;print $0}'
#以/为分隔符输出

 9. アレイ

#输出数组的下标位为1的数值
[root@localhost ~]# awk 'BEGIN{a[0]=1; a[1]=2; a[2]=3; print a[1]}' 
2
#输出数组的下标位为0的数值
[root@localhost ~]# awk 'BEGIN{a[0]=1; a[1]=2; a[2]=3; print a[0]}'
1
#也可以用字符串定义数组
[root@localhost ~]# awk 'BEGIN{a["abc"]=1; a["def"]=2; a["xyz"]=3; print a["abc"]}'
1
[root@localhost ~]# awk 'BEGIN{a["abc"]=1; a["def"]=2; a["xyz"]=3; print a["xyz"]}'
3
#输出数值和下标位
[root@localhost ~]# awk 'BEGIN{a[0]=1; a[1]=2; a[2]=3; for(i in a){print i,a[i]}}'
0 1
1 2
2 3

10. 重複チェック

#查询各种数值的重复次数
[root@localhost ~]# cat test.txt | awk '{a[$1]++};END{for(i in a){print i,a[i]}}'

 11. フィルターパスワードが失敗しました

awk '/Failed password/{ip[$11]++}END{for(i in ip){print i","ip[i],i}}' /var/log/secure | awk '$1>3{print $2}'
awk '/Invalid user/{print $10}' /var/log/secure | awk '{ip[$1]++}END{for(i in ip){print ip[i],i}}' | awk '$1>3{print $2}'

おすすめ

転載: blog.csdn.net/A1100886/article/details/130684780