English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

Linuxのawkコマンド

Linux コマンド全書

AWKはテキストファイルを処理する言語であり、強力なテキスト解析ツールです。

AWKと名付けられているのは、3人の創始者であるAlfred Aho、Peter Weinberger、およびBrian Kernighanの姓の最初の文字を取ったからです。

構文

awk [オプションパラメータ] 'script' var=value file(s)
または
awk [オプションパラメータ] -f scriptfile var=value file(s)

オプションパラメータの説明:

  • -F fs or --field-separator fs
    入力ファイルのフィールド区切り文字を指定します。fsは文字列または正規表現であり、例えば-F:。

  • -v var=value or --asign var=value
    ユーザー定義の変数に値を割り当てます。

  • -f scripfile or --file scriptfile
    スクリプトファイルからawkコマンドを読み取ります。

  • -mf nnn and -mr nnn
    nnn値に対して内在的な制限を設定します,-mfオプションはnnnに割り当てられる最大のブロック数を制限します;-mrオプションはレコードの最大数を制限します。これらの機能はBell研究所版awkの拡張機能であり、標準のawkでは適用されません。

  • -W compact or --compat, -W traditional or --traditional
    相容モードでawkを実行します。したがって、gawkの動作は標準のawkと完全に同じであり、すべてのawkエクステンションは無視されます。

  • -W copyleft or --copyleft, -W copyright or --copyright
    短い著作権情報を印刷します。

  • -W helpまたは --help, -W usageまたは --usage
    すべてのawkオプションと各オプションの短い説明を印刷します。

  • -W lintまたは --lint
    伝統的なUnixプラットフォームに移植できない構造に関する警告を印刷します。

  • -W lint-oldまたは --lint-old
    伝統的なUnixプラットフォームに移植できない構造に関する警告を印刷します。

  • -W posix
    互換モードを開きます。ただし、以下の制限があります:/x、関数キーワード、func、エスケープシーケンスおよびfsがスペースの場合、新しい行をドメイン区切り文字として;演算子**および**^および^=を置き換えることはできません;fflushは無効です。

  • -W re-intervalまたは --re-interval
    間隔正規表現の使用を許可します。参照(grepのPosix文字クラス),例えば括弧表現[[:alpha:]]。

  • -W ソースプログラム-textまたは --ソースプログラム-text
    プログラムを使用して-textをソースコードとして、-fコマンドを混用します。

  • -W バージョンまたは --バージョン
    bug報告情報のバージョンを印刷します。

基本用法

log.txtテキスト内容如下:

2 this is a test
3 Are you like awk
This's a test
10 There are orange,apple,mongo

用法一:

awk '{[pattern] action}' {filenames}   # 行一致文 awk '' はシングルクォートのみ使用できます

例:

# 各行をスペースまたはTABで分割し、テキスト中の1、4項
 $ awk '{print $1$4}' log.txt
 ---------------------------------------------
 2 a
 3 like
 This's
 10 orange,apple,mongo
 # フォーマット出力
 $ awk '{printf "%-8s %-10s\n",$1$4}' log.txt
 ---------------------------------------------
 2        a
 3        like
 This's
 10       orange,apple,mongo

用法二:

awk -F  #-Fは内蔵変数FSに相当し、分割文字を指定します

例:

# 使用","分割
 $  awk -F, '{print $1$2}'   log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # または使用内蔵変数
 $ awk 'BEGIN{FS=","} {print $1$2}'     log.txt
 ---------------------------------------------
 2 this is a test
 3 Are you like awk
 This's a test
 10 There are orange apple
 # 使用複数の区切り文字.まずスペースで分割し、分割結果に対して","で分割します
 $ awk -F '[ ,]'  '{print $1$2$5}'   log.txt
 ---------------------------------------------
 2 this test
 3 Are awk
 This's a
 10 There apple

用法三:

awk -v  # 設定変数

例:

 $ awk -va=1 '{print $1$1+a}' log.txt
 ---------------------------------------------
 2 3
 3 4
 This's 1
 10 11
 $ awk -va=1 -vb=s '{print $1$1+a,$1b}' log.txt
 ---------------------------------------------
 2 3 2s
 3 4 3s
 This's 1 This'ss
 10 11 10s

使用法4:

awk -f {awkスクリプト} {ファイル名}

例:

 $ awk -f cal.awk log.txt

演算子

演算子説明
= += -= *= /= %= ^= **=代入
?:C条件演算子
||論理OR
&&論理AND
~ そして !~正規表現に一致および不一致
< <= > >= != ==関係演算子
スペース結合
+ -加、減
* / %乗除、余数
+ - !一元加、減、論理否定
^ ***乗方
++ --増加または減少、接頭辞または接尾辞として使用
$フィールド参照
in配列メンバー

第一列がより大きい行をフィルタリング2の行をフィルタリング

$ awk '$1>2' log.txt    #コマンド
#出力
3 Are you like awk
This's a test
10 There are orange,apple,mongo

第一列が2の行をフィルタリング

$ awk '$1==2 {print1$3}' log.txt    #コマンド
#出力
2 is

第一列がより大きい行をフィルタリング2そして第二列が'Are'と等しい行

$ awk '$1>2 && $2=="Are" {print $1$2$3}' log.txt    #コマンド
#出力
3 Are you

内蔵変数

変数説明
$n現在のレコードのn番目のフィールド、フィールド間はFSで区切る
$0完全な入力レコード
ARGCコマンドライン引数の数
ARGINDコマンドライン中の現在のファイルの場所(0から始まる)
ARGVコマンドライン引数を含む配列
CONVFMT数字変換形式(デフォルト値は%.6g)ENVIRON環境変数関連配列
ERRNO最後のシステムエラーの説明
FIELDWIDTHSフィールド幅リスト(スペースキーで区切る)
FILENAME現在のファイル名
FNR各ファイルごとにカウントされる行番号
FSフィールド区切り文字(デフォルトはどんな空白)
IGNORECASEもし真なら、無視する大文字小文字のマッチを行います
NF一つのレコードのフィールドの数
NR既に読み込まれたレコード数、行番号、1開始
OFMT数字の出力形式(デフォルト値は%.6g)
OFS出力フィールド区切り文字、デフォルト値は入力フィールド区切り文字と一致。
ORS出力レコード区切り文字(デフォルトは一つの改行符)
RLENGTHmatch関数でマッチした文字列の長さ
RSレコード区切り文字(デフォルトは一つの改行符)
RSTARTmatch関数でマッチした文字列の最初の位置
SUBSEP配列のインデックス区切り文字(デフォルト値は/034)
$ awk 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "%---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1         5    1
log.txt    2    2         5    2
log.txt    2    3         3    3
log.txt    2    4         4    4
$ awk -F' 'BEGIN{printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n","FILENAME","ARGC","FNR","FS","NF","NR","OFS","ORS","RS";printf "%---------------------------------------------\n"} {printf "%4s %4s %4s %4s %4s %4s %4s %4s %4s\n",FILENAME,ARGC,FNR,FS,NF,NR,OFS,ORS,RS}'  log.txt
FILENAME ARGC  FNR   FS   NF   NR  OFS  ORS   RS
---------------------------------------------
log.txt    2    1        1    1
log.txt    2    2        1    2
log.txt    2    3        2    3
log.txt    2    4        1    4
# 出力順序号NR、マッチするテキスト行の番号
$ awk '{print NR,FNR,$1$2$3}' log.txt
---------------------------------------------
1 1 2 this is
2 2 3 Are you
3 3 This's a test
4 4 10 There are
# 出力分割符を指定
$  awk '{print1$2$5}' OFS=" $ "  log.txt
---------------------------------------------
2 $ this $ test
3 $ Are $ awk
This's $ a
10 $ There

正規表現を使用して、文字列をマッチ

# 第二列に「th」が含まれる行を出力し、第二列と第四列を印刷
$ awk '$2 ~ /th/ {print2$4}' log.txt
---------------------------------------------
this a

~ 表示パターンの開始。// 中はパターンです。

# 「re」を含む行を出力
$ awk '/re/ ' log.txt
---------------------------------------------
3 Are you like awk
10 There are orange,apple,mongo

大文字小文字を無視

$ awk 'BEGIN{IGNORECASE=1} /this/' log.txt
---------------------------------------------
2 this is a test
This's a test

パターン反転

$ awk '$2 !~ /th/ {print2$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo
$ awk '!/th/ {print2$4}' log.txt
---------------------------------------------
Are like
a
There orange,apple,mongo

awkスクリプト

awkスクリプトについて、注意すべき二つのキーワードであるBEGINとENDに注意してください。

  • BEGIN{ここには、実行前に実行する命令が入ります }

  • END {ここには、すべての行を処理した後に実行する命令が入ります }

  • {ここには、各行を処理する際に実行する命令が入ります}

以下のようなファイル(学生の成績表)があります:

$ cat score.txt
Marry   2143 78 84 77
Jack    2321 66 78 45
Tom     2122 48 77 71
Mike    2537 87 97 95
Bob     2415 40 57 62

以下は、awkスクリプトです:

$ cat cal.awk
#!/bin/awk -f
#実行前
BEGIN {
    数学 = 0
    英語 = 0
    コンピュータ = 0
 
    printf "NAME    NO.   MATH  ENGLISH  COMPUTER   TOTAL\n"
    printf "---------------------------------------------\n"
}
#実行中
{
    数学+=$3
    英語+=$4
    コンピュータ+=$5
    printf "%-6s %-6s %4d %8d %8d %8d\n、1、2、3$4$5、3+$4+$5
}
#実行後
END {
    printf "---------------------------------------------\n"
    printf "  合計:%10d %8d %8d \n", math, english, computer
    printf "平均値:%10.2f %8.2f %8.2f\n", math/NR, english/NR, computer/NR
}

実行結果を見てみましょう:

$ awk -f cal.awk score.txt
NAME    NO.   MATH  ENGLISH  COMPUTER   合計
---------------------------------------------
Marry  2143     78       84       77      239
Jack   2321     66       78       45      189
Tom    2122     48       77       71      196
Mike   2537     87       97       95      279
Bob    2415     40       57       62      159
---------------------------------------------
  合計:       319      393      350
平均値:     63.80    78.60    70.00

他の例

AWKのhello worldプログラムは:

BEGIN { print "Hello, world!" }

ファイルサイズを計算する

$ ls -l *.txt | awk '{sum+=$5} END {print sum}
--------------------------------------------------
666581

ファイルから長さが大于 80の行:

awk 'length>80' log.txt

九九乘法表を印刷する

seq 9 | sed 'H;g' | awk -v RS='' '{for(i=1;i<=NF;i++)printf("%dx%d=%d%s", i, NR, i*NR, i==NR?"\n":"\t")'

Linux コマンド全書