便利なデータ処理ツールawk(十分に詳細です!)

便利なデータ処理ツールawk

1つ、awkエディター

1.動作原理:

デフォルトではスペースまたはタブで区切られたテキストを1行ずつ読み取り、区切られたフィールドを組み込み変数に保存し、モードまたは条件に従って編集コマンドを実行します。

sedコマンドは、行全体を処理するためによく使用されますが、awkは、行を複数の「フィールド」に分割してから処理する傾向があります。awk情報の読み取りも1行ずつ読み取られ、print関数を使用して実行結果をフィールドデータとともに印刷および表示することができます。awkコマンドを使用するプロセスでは、論理演算子「&&」を使用して「and」を示し、「||」を使用して「or」を示し、「!」を使用して「not」を示すことができます。簡単な数学演算を実行することもできます。 、+、-、*、/、%、^などは、それぞれ加算、減算、乗算、除算、剰余、および累乗を表します。

2.コマンド形式:

awk  选项   '模式或条件 {操作}'  文件1   文件2...
awk  -f   脚本文件   文件1    文件2...

3. awkの一般的な組み込み変数(直接使用可能)は次のとおりです。

FS:列区切り文字。テキストの各行にフィールド区切り文字を指定します。デフォルトはスペースまたはタブストップです。「-F」と同じ効果があります
。NF:現在処理されている行のフィールドの数。
NR:
現在処理されている行の行番号(序数)$ 0:現在処理されている行の行全体。
$ n:現在処理されている行のn番目のフィールド(列n)
FILENAME:処理されているファイルの名前。
RS:行区切り文字。awkがファイルからデータを読み取る場合、RSの定義に従ってデータを多くのレコードに分割しますが、awkは処理のために一度に1つのレコードのみを読み取ります。デフォルト値は「\ n」です

2、awkの使い方

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

①すべてのコンテンツを出力する

awk  '{print}'  file
awk '{print $0}’ file
[root@localhost ~] # awk  '{print}'  shuzi.txt 
one
two
three
four
five
[root@localhost ~] # awk  '{print $0}'  shuzi.txt 
one
two
three
four
five

②指定した行の内容を出力します

awk 'NR==1, NR==3{print}'  file  #输出第1-3行内容
awk '(NR>=1) && (NR<=3) {print}' file #输出第1-3行内容

awk 'NR==1 || NR==3 {print}' file #输出第1行、第3行内容

[root@localhost ~] # awk 'NR==1, NR==3{print}' shuzi.txt 
one
two
three
[root@localhost ~] # awk '(NR>=1) && (NR<=3)  {print}' shuzi.txt 
one
two
three
[root@localhost ~] # awk  'NR==1 || NR==3 {print}' shuzi.txt 
one
three

③奇数行または偶数行の内容を出力する

awk '(NR%2)==1{print}'  file #除以2余数为1为奇数,输出奇数行
awk '(NR%2)==0{print}'  file #除以2余数为0为偶数,输出偶数行
[root@localhost ~] # awk '(NR%2)==1{print}' shuzi.txt 
one
three
five
[root@localhost ~] # awk '(NR%2)==0{print}' shuzi.txt 
two
four

④指定した文字列で開始または終了する行の内容を出力します

awk '/^root/{print}' /etc/passwd #输出以root开头的内容
awk '/nologin$/{print}' /etc/passwd #输出以nologin结尾的内容
[root@localhost ~] # awk '/^root/{print}' /etc/passwd
root:x:0:0:root:/root:/bin/bash
[root@localhost ~] # awk '/nologin$/{print}' /etc/passwd
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
adm:x:3:4:adm:/var/adm:/sbin/nologin
lp:x:4:7:lp:/var/spool/lpd:/sbin/nologin
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
operator:x:11:0:operator:/root:/sbin/nologin
games:x:12:100:games:/usr/games:/sbin/nologin
ftp:x:14:50:FTP User:/var/ftp:/sbin/nologin
nobody:x:99:99:Nobody:/:/sbin/nologin
...

⑤指定した文字列に関連する行数をカウントします

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

awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd
#统计以/bin/bash结尾的行数,等同于
grep  -c "/bin/bash$"  /etc/passwd
[root@localhost ~] # awk 'BEGIN {x=0};/\/bin\/bash$/{x++};END {print x}' /etc/passwd
2
[root@localhost ~] # grep  -c "/bin/bash$"  /etc/passwd
2
[root@localhost ~] # grep "/bin/bash$"  /etc/passwd
root:x:0:0:root:/root:/bin/bash
muhonghuan:x:1000:1000:muhonghuan:/home/muhonghuan:/bin/bash

2.テキストを出力するフィールドを指定します

#输出每行中(以”:“分割的)的第三个字段
awk -F ":" '{print $3}' /etc/passwd          

#输出每行中(以”:“分割的)的第1,3个字段
awk -F ":" '{print $1,$3}' /etc/passwd      

#输出第三个字段的值小于5的行的第1,3个字段
awk -F ":" '$3<5{print $1,$3}' /etc/passwd   

#输出第三个字段的值不小于200的行的内容
awk -F ":" '!($3<200){print}' /etc/passwd    
awk 'BEGIN {FS=":"};{if ($3>=200){print}}'  /etc/passwd   

#($3>$4)?$3:$4是三元运算符,如果第三个字段的值大于第四个字段的值,则把第三个字段的值赋给max,否则把第四个字段的值赋给max
awk -F ":" '{max=($3>$4)?$3:$4;{print max}}' /etc/passwd

#输出内行的内容和行号,每处理完一条记录,NR值(当前处理的行的行号)加1
awk -F ":" '{print NR,$0}' /etc/passwd        

#输出以冒号分隔且第7个字段中包含/bash的行的第1个字段
awk -F ":" '$7~"/bash"{print $1}' /etc/passwd    

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

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

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

①コロンで区切られたテキスト段落の数を数えます。END{}ステートメントブロックには、結果の印刷などのステートメントが配置されることがよくあります。

[root@localhost ~] # echo $PATH | awk 'BEGIN{RS=":"};END{print NR}'
5
[root@localhost ~] # echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

②bashを使用しているユーザーの数を数える

[root@localhost ~] # awk -F ":" '/bash$/{print | "wc -l"}' /etc/passwd
2
[root@localhost ~] # grep -c "bash$" /etc/passwd
2

③メモリ使用量の割合を見る

最初にfree-mをチェックしてから、Mem(3番目のフィールドの値を(3番目のフィールドの値+ 4番目のフィールドの値)で割った値)を使用し、100を掛けてメモリ使用率を求めます。

[root@localhost ~] # free -m
              total        used        free      shared  buff/cache   available
Mem:           1823         278        1145           9         398        1336
Swap:          4095           0        4095
[root@localhost ~] # free -m | awk '/Mem:/ {print int($3/($3+$4)*100)}'
19

④CPUアイドル率を確認する

topは動的ビューであるため、(-b -n 1)は、出力結果が1回だけ必要であることを意味します。
文全体のコマンドは、次のことを意味します。1つのプロセスの結果を動的に出力する(top -b -n 1); CPUをフィルターで除外するline(grep Cpu);カンマで区切って、4番目の列を出力します(awk -F '、' '{print $ 4}');次に、フィルター処理された4番目の列の最初の値を出力します(awk '{print $ 1}')

[root@localhost ~] # top -b -n 1 | grep Cpu | awk -F ',' '{print $4}' | awk '{print $1}'
100.0
[root@localhost ~] # top -b -n 1
top - 20:54:28 up  8:28,  2 users,  load average: 0.00, 0.01, 0.05
Tasks: 139 total,   1 running, 138 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  6.2 sy,  0.0 ni, 93.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st

⑤最後のシステム再起動時刻を確認してください

#显示上次系统重启时间,等同于uptime;second ago为显示多少秒前的时间,+"%F %H:%M:%S"等同于+"%Y-%m-%d %H:%M:%S"的时间格式
date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"

[root@localhost ~] # uptime
 20:57:15 up  8:31,  1 user,  load average: 0.00, 0.01, 0.05
[root@localhost ~] # date -d "$(awk -F "." '{print $1}' /proc/uptime) second ago" +"%F %H:%M:%S"
2021-01-03 12:25:41

⑥wコマンドを呼び出して、オンラインユーザー数をカウントします

最初の2行は情報表示専用であり、オンラインユーザー向けではないため、カウントするときは2を引きます

[root@localhost ~] # awk 'BEGIN {while ("w" | getline) n++ ; {print n-2}"%"}'
1
[root@localhost ~] # w
 20:59:45 up  8:34,  1 user,  load average: 0.00, 0.01, 0.05
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
root     pts/0    192.168.2.1      19:57    1.00s  0.06s  0.00s w

✓ホスト名を呼び出し、現在のホスト名を出力します

[root@localhost ~] # hostname
localhost.localdomain
[root@localhost ~] # awk 'BEGIN {"hostname" | getline ; {print $0}}'
localhost.localdomain

⑧CPU使用率を表示

cpu_us='top -b -n 1 | grep Cpu | awk '(print $2}'
cpu_sy='top -b -n 1 | grep Cpu | awk -F ','  '{print $2}'  | awk  '{print $1}'  
cpu_sum=$ ( ($cpu_us+$cpu_sy))
echo $cpu_sum

サプリメント:getline

  • getlineの左右にリダイレクト文字「<」または「|」がない場合、getlineは現在のファイルに作用し、現在のファイルの最初の行を変数varまたは$ 0に読み取り、その後にawkがgetlineを処理する前にすでに行を読み取っているので、getlineの戻り結果はインターレースされます。
  • getlineの左右にリダイレクト文字「<」または「|」がある場合、getlineは方向入力ファイルに作用します。ファイルは開かれたばかりで、awkによって行に読み込まれていないため、次の方法でのみ読み込まれます。 getlineの場合、getlineはこれを返します。ファイルの最初の行であり、1行おきではありません。
[root@localhost ~] # cat shuzi.txt 
one
two
three
four
five
six
seven
eight
nine
ten

#输出奇数行
awk读取第一行,print打印第一行,getline获取第二行;
awk读取第三行,print打印第三行,getline获取第四行;
awk读取第五行,print打印第五行,getline获取第六行;
以此类推
[root@localhost ~] # seq 10 | awk '{print $0; getline}' shuzi.txt 
one
three
five
seven
nine

#输出偶数行
awk读取第一行,getline获取第二行,print打印第二行;
awk读取第三行,getline获取第四行,print打印第四行;
awk读取第五行,getline获取第六行,print打印第六行;
以此类推
[root@localhost ~] # seq 10 | awk '{getline; print $0}' shuzi.txt 
two
four
six
eight
ten

おすすめ

転載: blog.csdn.net/qq_35456705/article/details/112155852