1. ホーム
  2. シェル

linux awkコマンド詳細説明

2022-02-28 19:17:51

awk はラインプロセッサです。 : 画面処理より有利、大きなファイルを扱ってもメモリのオーバーフローや処理の遅れがない、テキスト情報をフォーマットするのによく使われる

awkのプロセスです。  各行を順番に処理し、出力する

awkのコマンド形式です。

awk [-F|-f|-v] 'BEGIN{}. //{command1; command2} END{}' ファイル

 [F|-f|-v] 大きな引数、-F はセパレータを指定、-f はスクリプトを起動、-v は変数 var=value を定義する。

' ' 引用コードブロック

BEGIN はコードブロックを初期化し、各行を処理する前に、主にグローバル変数の参照と FS セパレータの設定によりコードを初期化します。

// コードブロックに文字列または正規表現でマッチングさせる

1つ以上のコマンドを含む{}コマンドブロック

セミコロンで区切られた複数のコマンドです。

各行が処理された後に実行される END 閉鎖ブロック。主に最終的な計算を行うか、閉鎖サマリー情報を出力する。

特別なポイント

現在の行全体に対して$0

$1 各行の最初のフィールド

NF フィールド数変数

NR 行ごとのレコード番号、複数のファイルレコードの場合はインクリメントされる

FNRはNRと似ていますが、複数ファイルのレコードは増分されず、各ファイルは1から始まります。

\タブレータ

\⑭改行

FS BEGINでセパレータを定義する

RS入力レコードのセパレータ、デフォルトは改行(つまり、テキストは行ごとに入力される)。

~ との完全比較ではありません。

! ~ は一致しない、完全比較ではない

== 等しい、すべて等しい、完全比較

! = not equal, 厳密な比較

との論理

|ロジカルまたは

+ はマッチング時に1以上を示す

/[0-9][0-9]+/ 2桁以上の数字

/[0-9][0-9]*/ 1桁またはそれ以上の数字

FILENAME ファイル名

OFS 出力フィールドの区切り文字。デフォルトではスペースですが、タブなどに変更することも可能です。

ORS出力レコードセパレーター、デフォルトは改行、つまり結果も1行ずつ画面に出力されます。

-F '[:#/]' は3つのセパレータを定義します。

プリント & $0

print は指定された内容を出力する awk のメインコマンドです。

awk '{print}' /etc/passwd == awk '{print $0}' /etc/passwd  

awk '{print " "}' /etc/passwd // passwd の内容を出力する代わりに、同じ数の空行を出力します。これは awk がテキストを一度に一行ずつ処理することをさらに説明します。

awk '{print "a"}' /etc/passwd //同じ数の a 行を出力し、1 行には a の文字が 1 つだけある

awk -F":" '{print $1}' /etc/passwd 

awk -F: '{print $1; print $2}' /etc/passwd //テキストの行ごとの処理をさらに理解するために、それぞれの行の最初の 2 つのフィールドを別々の行に置く

awk -F: '{print $1,$3,$6}' OFS="\t" /etc/passwd //フィールド 1,3,6 を出力、タブで区切られる

-f はスクリプトファイルを指定します。

awk -f script.awk ファイル

BEGIN{ <未定義

FS=":"

{print $1} // awk -F":" '{print $1}' と同じ効果ですが、セパレータが FS を使ってコード自体で指定されていることが異なります。

awk 'BEGIN{X=0} /^$/{ X+=1 } END{print "I find",X,"blank lines."}' test 

4行の空白行を見つける。

 ls -l|awk 'BEGIN{sum=0} ! /^d/{sum+=$5} ! END{print "合計サイズは",sum}' //ファイルサイズの計算

合計サイズは17487

-F はセパレータを指定します

$1 は指定されたセパレーターの後の最初のフィールド、$3 は 3 番目のフィールド、そして \t はタブを指します。

1つ以上の連続したスペースまたはタブを区切り文字と見なし、複数のスペースを1つのスペースと見なす

awk -F":" '{print $1}' /etc/passwd

awk -F":" '{print $1 $3}' /etc/passwd //$1 と $3 は分離せず、連結して出力されます。

awk -F":" '{print $1,$3}' /etc/passwd // カンマが追加され、$1と$3はスペースで区切られています。

awk -F":" '{print $1 " " $3}' /etc/passwd //$1と$3の間にスペースを追加する。

awk -F":" '{print "ユーザ名:" $1 "\t Uid:" $3 }' /etc/passwd /カスタム出力  

awk -F: '{print NF}' /etc/passwd //1行にいくつのフィールドがあるか表示します。

awk -F: '{print $NF}' /etc/passwd // 各行で NF 番目のフィールドの値を表示します。

 awk -F: 'NF==4 {print }' /etc/passwd //フィールドが4つしかない行を表示する

awk -F: 'NF>2 {print $0}' /etc/passwd //1行に2つ以上のフィールドがある行を表示する

awk '{print NR,$0}' /etc/passwd // 各行の行番号を出力します。

awk -F: '{print NR,NF,$NF,"\t",$0}' /etc/passwd //行番号、フィールド数、最後のフィールド値、タブ、各行の内容を順番に表示する。

awk -F: 'NR==5{print}' /etc/passwd //5行目を表示する

awk -F: 'NR==5 || NR==6{print}' /etc/passwd //5行目と6行目を表示します。

route -n|awk 'NR!=1{print}' //先頭行を表示しない。

//コードブロックのマッチング

//純粋な文字の一致 ! //純粋な文字の不一致    ~//フィールド値が一致しました。~//フィールド値が一致しない ~/a1|a2/ フィールド値がa1またはa2に一致する   

awk '/mysql/' /etc/passwd

awk '/mysql/{print }' /etc/passwd

awk '/mysql/{print $0}' /etc/passwd // 3つのコマンドで同じ結果になります。

awk '! /mysql/{print $0}' /etc/passwd //mysqlにマッチしない行の出力

awk '/mysql|mail/{print}' /etc/passwd

awk '! /mysql|mail/{print}' /etc/passwd

awk -F: '/mail/,/mysql/{print}' /etc/passwd // 区間一致

awk '/[2][7]*/{print $0}' /etc/passwd //27を数字の頭に含む行にマッチ、例:27、277、2777...など。

awk -F: '$1~/mail/{print $1}' /etc/passwd //$1 は指定した内容にマッチしてから表示されます。

awk -F: '{if($1~/mail/) print $1}' /etc/passwd //上記と同じです。

awk -F: '$1!~/mail/{print $1}' /etc/passwd //マッチしません。

awk -F: '$1!~/mail|mysql/{print $1}' /etc/passwd        

IFステートメント

は必ず{}で使用し、比較は()で展開します。

awk -F: '{if($1~/mail/) print $1}' /etc/passwd //短縮されました。

awk -F: '{if($1~/mail/) {print $1}}'. /etc/passwd // オールキャプス

awk -F: '{if($1~/mail/) {print $1} else {print $2}}'. /etc/passwd //if... .... . else...

条件式

== ! = > >=  

awk -F":" '$1=="mysql"{print $3}' /etc/passwd  

awk -F":" '{if($1=="mysql") print $3}' /etc/passwd // 上記と同じです。 

awk -F":" '$1!="mysql"{print $3}' /etc/passwd //同じではない

awk -F":" '$3>1000{print $3}' /etc/passwd // より大きいです。

awk -F":" '$3>=100{print $3}' /etc/passwd // 以上の値

awk -F":" '$3<1{print $3}' /etc/passwd //以下略

awk -F":" '$3<=1{print $3}' /etc/passwd //以下となる。

論理演算子

&& || 

awk -F: '$1~/mail/ && $3>8 {print }' /etc/passwd //論理的に、$1はメール、$3>8と一致します。

awk -F: '{if($1~/mail/ && $3>8) print }' /etc/passwd

awk -F: '$1~/mail/ || $3>1000 {print }' /etc/passwd //論理的または

awk -F: '{if($1~/mail/ || $3>1000) print }' /etc/passwd 

数値演算

awk -F: '$3 > 100' /etc/passwd    

awk -F: '$3 > 100 || $3 < 5' /etc/passwd  

awk -F: '$3+$4 > 200' /etc/passwd

awk -F: '/mysql|mail/{print $3+10}' /etc/passwd //3番目のフィールドに10を加えて表示する 

awk -F: '/mysql/{print $3-$4}' /etc/passwd //差し引く

awk -F: '/mysql/{print $3*$4}' /etc/passwd //multiply(掛け算)

awk '/MemFree/{print $2/1024}' /proc/meminfo //divide

awk '/MemFree/{print int($2/1024)}' /proc/meminfo //丸め方

出力セパレータ OFS

awk '$6 ~ /FIN/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt

awk '$6 ~ /WAIT/ || NR==1 {print NR,$4,$5,$6}' OFS="\t" netstat.txt        

// フィールド 6 が WAIT に一致する行を出力し、各行番号が出力され、フィールド 4,5,6 がタブで分割されている。

処理結果をファイルに出力する

コマンドコードブロックで直接出力する route -n|awk 'NR!=1{print > "。/fs"}'   

リダイレクトで出力する場合 route -n|awk 'NR!=1{print}' > . /fs

出力の書式設定

netstat -anp|awk '{printf "%-8s %-8s %-10sn",$1,$2,$3}' 

printfは書式出力を意味する

% フォーマットされた出力セパレータ

-8 長さは8文字です

sは文字列型

各行の最初の3フィールドを出力し、最初のフィールドは文字列型(長さ8)、2番目のフィールドは文字列型(長さ8)を出力するように指定します。

3番目のフィールドは、文字列型(長さ10)を出力します。

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-10s %-10s %-10s \n",$1,$2,$3}'

netstat -anp|awk '$6=="LISTEN" || NR==1 {printf "%-3s %-10s %-10s ¢n",NR,$1,$2,$3}'

IFステートメント

awk -F: '{if($3>100) print "large" else print "small"}' /etc/passwd・・・・・・・・・・・?

小さい

小さい

小さい

大きい

小さい

小さい

awk -F: 'BEGIN{A=0;B=0}. {if($3>100) {A++; print "大"} else {B++; print "小"}}。END{print A,"\t",B}' /etc/passwd 

                                                                                                                  //IDが100以上の場合、A+1、それ以外の場合B+1

awk -F: '{if($3<100) next; else print}' /etc/passwd //100 以下をスキップ、それ以外を表示

awk -F: 'BEGIN{i=1}. {if(i<NF) print NR,NF,i++ }' /etc/passwd   

awk -F: 'BEGIN{i=1}. {if(i<NF) {print NR,NF} i++ }' /etc/passwd

の別形式

awk -F: '{print ($3>100 ? "yes":"no")}' /etc/passwd・・・・・・・・・・? 

awk -F: '{print ($3>100 ? $3":\tyes":$3":\tno")}' /etc/passwdを実行します。

whileステートメント

awk -F: 'BEGIN{i=1}. {while(i<NF) print NF,$i,i++}' /etc/passwd 

7 root 1

7 x 2

7 0 3

7 0 4

7 ルート 5

7 /root 6

配列

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) print i,"\t",a[i]}'.

netstat -anp|awk 'NR!=1{a[$6]++} END{for (i in a) printf "%-20s %-10s %-5s \n", i,"\t",a[i]}'

9523 1     

9929 1     

リスニング 6     

7903 1     

3038/cupsd 1     

7913 1     

10837 1     

9833 1     

アプリケーション1

awk -F: '{print NF}' helloworld.sh // 出力ファイル 1 行にいくつのフィールドがあるか

awk -F: '{print $1,$2,$3,$4,$5}' helloworld.sh //最初の5つのフィールドを出力する

awk -F: '{print $1,$2,$3,$4,$5}' OFS='\t' helloworld.sh //最初の5フィールドを出力し、出力をタブ区切りにします。

awk -F: '{print NR,$1,$2,$3,$4,$5}' OFS='\t' helloworld.sh //Tab-separated output of the first 5 fields and print line number.

アプリケーション2

awk -F '[:#]' '{print NF}' helloworld.sh //複数のセパレータを指定する。#1行にいくつのフィールドを出力するか

awk -F'[:#]' '{print $1,$2,$3,$4,$5,$6,$7}' OFS='\t' helloworld.sh //Tab-separated output of multiple fields.

アプリケーション3

awk -F '[:#/]' '{print NF}' helloworld.sh //3つのセパレータを指定し、1行のフィールド数を出力します。

awk -F'[:#/]' '{print $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12}' helloworld.sh //複数フィールドをタブ区切りで出力

アプリケーション4

KBを単位に、/homeディレクトリにある通常のファイルのサイズを計算します。

ls -l|awk 'BEGIN{sum=0} ! /^d/{sum+=$5} ! END{print "総サイズは:",sum/1024,"KB"}'

ls -l|awk 'BEGIN{sum=0} ! /^d/{sum+=$5} ! END{print "total size is:",int(sum/1024),"KB"}' //intは四捨五入のため。

アプリ5

netstat -anp status LISTENとCONNECTでそれぞれ接続数をカウントする。

netstat -anp|awk '$6~/LISTEN|CONNECTED/{sum[$6]++} END{for (i in sum) printf "%-10s %-6s %-3s \n", i,"",sum[i]}'

アプリ6

ホームディレクトリにある異なるユーザーの共通ファイルの総数は何個ですか?

ls -l|awk 'NR!=1 && ! /^d/{sum[$3]++} END{for (i in sum) printf "%-6s %-5s %-3s \n",i,"",sum[i]}'   

mysql 199 

ルート 374 

ホームディレクトリにある異なるユーザーの共通ファイルの合計サイズはいくらですか?

ls -l|awk 'NR!=1 && ! /^d/{sum[$3]+=$5}. END{for (i in sum) printf "%-6s %-5s %-3s %-2s \n",i,",sum[i]/1024/1024,"MB"}'.

アプリケーション7

成績表の書き出し

awk 'BEGIN{math=0;eng=0;com=0;printf "リネノ。Name No. Math English Computer Totaln";printf "------------------------------ ------------------------------n"}{math+=$3; eng+=$4; com+=$5;printf "%-8s %-7s %-7s %-9s %-10s %-7s \n",NR,$1,$2,$3,$4, $5,$3+4+$5} {Math+=%7s %7s %7s } {Math=%9s %9s %9S %9R$3 } {Math+=%9s %9S %9L$3} {Math+=%9s %9L$3} {Math+=%9s %9L$3 END{printf "------------------------------------------------------------n";printf "%-24s %-7s %-9s %-20s \n& quot;,"Total:",math,eng,com;printf "%-24s %-7s %-9s %-20s \n","Avg:",math/NR,eng/NR,com/NR}' test0


[root@localhost home]# cat test0 

マリー 2143 78 84 77

ジャック 2321 66 78 45

トム 2122 48 77 71

マイク 2537 87 97 95

ボブ 2415 40 57 62