1. はじめに
awk には awk、nawk、gawk の 3 つのバージョンがあります。特に指定がない限り、一般的に gawk を指します。 awk 言語の最も基本的な機能は、指定された規則に基づいてファイルまたは文字列から情報を分解して抽出することであり、指定された規則に基づいてデータを出力することもできます。完全な awk スクリプトは通常、テキスト ファイル内の情報をフォーマットするために使用されます。
2. 基本構文
awk [opion] 'awk_script' input_file1 [input_file2 ...]
awk の共通オプションは次のとおりです:
① -F fs: 省略された場合、入力レコードのフィールド区切り文字として fs を使用します。オプションで、awk は環境変数 IFS の値を使用します
② -f filename: ファイル filename から awk_script を読み取ります
③ -v var=value: awk_script の変数を設定します
awk には 3 つの実行モードがあります。 、コマンド内に awk スクリプト コマンドを直接入れます。
2 番目に、awk のすべてのスクリプト コマンドをスクリプト ファイルに配置し、-f オプションを使用して実行するスクリプト コマンド ファイルを指定します。
3 番目の方法は、awk_script をスクリプト ファイルに配置し、最初の行として #!/bin/awk -f を使用し、スクリプトの実行許可を与え、シェルにスクリプト名を入力して呼び出します。
3. awk スクリプト
awk スクリプトは 1 つ以上の awk_cmd で構成できます。1 つの awk_cmd が完了した後、新しい行を開始して区切る必要があります。
awk_cmd は、awk_pattern {アクション} の 2 つの部分で構成されます。
さらに、awk コマンドで awk_script を直接使用する場合、awk_script を複数行で記述することもできますが、awk_script 全体が一重引用符で囲まれていることを確認する必要があります。
awk コマンドの一般形式:
awk ' BEGIN { アクション }
awk_pattern1 { アクション }
......
awk_patternN { アクション }
END { アクション }
' inputfile
ここで、BEGIN { アクション } と END { アクション } はオプションです。
次のように、awk スクリプトで AWK 独自の組み込み変数を使用できます:
ARGC コマンドライン引数の数
ARGV コマンドライン引数の配列
FILENAME 現在の入力ファイル名
FNR レコード番号現在のファイル内
FS 入力フィールド区切り文字、デフォルトはスペース
RS 入力レコード区切り文字
NF 現在のレコード内のフィールド数
NR これまでのレコード数
OFS 出力フィールド区切り文字
ORS 出力レコード区切り文字
awk スクリプトの実行プロセス:
① BEGIN ブロックが存在する場合、awk はそれに指定されたアクションを実行します。
② awk は入力ファイルから 1 行を読み取ります。これは入力レコードと呼ばれます。 (入力ファイルを省略した場合は標準入力から読み込まれます)
③ awkは読み取ったレコードをフィールドに分割し、最初のフィールドを変数$1に、2番目のフィールドを$2、というように配置します。 $0 はレコード全体を表します。フィールド区切り文字は、シェル環境変数 IFS を使用するかパラメータによって指定されます。
④ 現在の入力レコードと各 awk_cmd の awk_pattern を比較し、一致する場合は、対応するアクションを実行します。一致するものがない場合、すべての awk_cmd が比較されるまで、対応するアクションはスキップされます。
⑤ 入力レコードがすべての awk_cmd を比較すると、awk は入力の次の行を読み取り、ステップ③と④を繰り返します。このプロセスは、awk がファイルの終わりを読み取るまで続きます。
⑥ awk がすべての入力行を読み込んだとき、END が存在すれば、対応するアクションが実行されます。
1) input_file は複数のファイルを含むファイルリストにすることができ、awk はリスト内の各ファイルを順番に処理します。
2) awk_cmd の awk_pattern は省略可能です。省略した場合、入力レコードの照合や比較を行わずに、対応するアクションが実行されます。 awk_cmd アクションは省略することもできます。省略した場合、デフォルトのアクションは現在の入力レコード、つまり {print $0} を出力します。 awk_cmd 内の awk_pattern とアクションを同時に省略することはできません。
3) BEGIN ブロックと END ブロックは、それぞれ awk_script の先頭と最後に配置されます。 awk_script では、END ブロックまたは BEGIN ブロックのみが許可されます。 awk_script に BEGIN {actions } しかない場合、awk は input_file を読み取りません。
4) awk は入力ファイルのデータをメモリに読み取り、メモリ内の入力データのコピーを操作しますが、入力ファイルの内容は変更されません。
5) awk は常に標準出力に出力します。 awk をファイルに出力したい場合は、リダイレクトを使用できます。
3.1.awk_pattern
awk_pattern パターン部分は、アクションのアクション部分がいつトリガーされるか、およびアクションがいつトリガーされるかを決定します。
awk_pattern には次のタイプがあります:
1) 正規表現は awk_pattern として使用されます: /regexp/
正規表現 regexp は / でラップする必要があることに注意してください
awk の正規表現マッチング操作でよく使用されます文字:
^ $ . [] | () * //: ユニバーサル正規表現メタ文字
+: awk 独自のメタ文字であり、grep や sed などには適用されません。
? : 前の単一文字と 1 回または 0 回一致します。これは awk 独自のメタ文字であり、grep や sed には適していません。 正規表現の詳細については、「正規表現」を参照してください。 例: awk '/ *$0.[0-9][0-9].*/' input_fileたとえば、行の内容は $0.99 です。hello 行は上記の正規表現と一致します2) ブール式は次のように使用されます。 awk_pattern。式が true の場合、対応するアクションの実行がトリガーされます。 ① 変数 (フィールド変数 $1、$2 など) と /regexp/② ブール式の演算子:関係演算子: < > <= >= == !=
一致演算子: value ~ /regexp/ 値が /regexp/ に一致する場合、 true
value を返します !~ /regexp/ if value /regexp / が一致しない場合は true を返します
例: awk '$2 > 10 {print "ok"}' input_file
awk '$3 ~ /^d/ {print "ok"}' input_file
③ &&( そして) と ||(or) は、2 つの /regexp/ またはブール式を接続して、混合式を形成できます。 !(not) は、ブール式内または /regexp/ の前で使用できます。
例: awk '($1 < 10 ) && ($2 > 10) {print $0 "ok"}' input_file
awk '/^d/ || {print $0 "ok"}' input_file
④ 代入式など、他の式が awk_script として使用されます
例:
awk '(tot+=$6) END{print "total Points :" tot }' input_file // セミコロンは使用できません省略
awk 'tot+=$6 {print $0} END{print "total Points :" tot }' input_file // 上記と同等
代入式を使用する場合、代入される変数が数値の場合、 0 以外の場合は一致し、それ以外の場合は一致しません。文字列の場合、空でない場合は一致し、それ以外の場合は一致しません。
awk 組み込み文字列関数:
gsub(r, s) $0 全体で r を s に置き換えます
awk 'gsub(/name/,"xingming") {print $0}' temp
gsub ( r, s, t) t 全体の r を s に置き換えます
index(s,t) s
awk 内の文字列 t の最初の位置を返します 'BEGIN {printindex("Sunny", "ny") } ' temp 4
length(s) を返します s
match(s, r) の長さを返します r
awk に一致する文字列が s に含まれているかどうかをテストします '$1=="J.Lulu" {print match($1, " u")}' temp Return 4
split(s, a, fs) fs
awk で s をシーケンス a に分割します 'BEGIN {print split("12#345#6789", myarray, "#") "'
は 3 を返しますが、myarray[1]="12"、myarray[2]="345"、myarray[3]="6789"
sprint(fmt, exp) fmt でフォーマットされた exp を返します
sub(r , s) $0 の左端の最長部分文字列の r を s に置き換えます (最初に一致する文字列のみを置き換えます)
substr(s, p) p から文字列 s を返します 開始サフィックス部分
substr(s, p, n ) 文字列 s 内の p から始まり長さ n のサフィックス部分を返します
awk 文字列連結操作
[chengmo@centos5 ~]$ awk 'BEGIN{a= "a";b="b";c= (a""b);print c}'
ab
2.7. printf 関数の使用:
文字変換: echo "65" |awk '{printf " %cn", $0}' 出力 A
awk 'BEGIN {printf "%fn", 999}' 出力 999.000000
フォーマットされた出力: awk '{printf "%-15s %sn", $1, $3}' temp 最初のフィールドをすべて左揃えにします
2.8 その他。 awk の使用法:
awk コマンドの行に値を渡す:
awk '{if ($5
who | awk '{if ($1==user) print $1 " are in " $2 ' user=$LOGNAME 使用環境変数
awk スクリプト コマンド:
の先頭に !/bin/awk -f を使用します。この文がないと、自己完結型スクリプトは実行されません。 例:
!/bin /awk -f
#すべてのコメント行はハッシュ '#' で始まる必要があります
# name:student_tot.awk
# 呼び出し先:student_tot.awk Grade.txt
# クラブ学生ポイントの合計と平均を出力します
# 最初にヘッダーを出力します
BEGIN
{
「学生の日付、メンバー番号、学年、年齢、最大ポイント」を印刷
「名前、参加、獲得可能なポイント」を印刷
"印刷"========== ======= ========================================="
}
# を追加しましょう獲得ポイント数
(tot+=$6);
# 処理が完了しました。合計ポイントと平均ポイントを出力しましょう
END
{
print "クラブ生徒の合計ポイント:" tot
Print "クラブ生徒の平均ポイント:" tot/N
}
2.9. awk array:
awkの基本的なループ構造
For(配列の要素) print array[element]
awk 'BEGIN {record="123#456# 789";split(record, myarray, "#")}
END { for (i in myarray) {print myarray[i]} }
3.0 awkのカスタム文
1. 条件判定文(if)
if (式) #if (配列内の変数)
ステートメント 1
else
ステートメント 2
形式では、「ステートメント 1」は複数のステートメントを指定できます。Unix awk の判断とユーザーの独自の解釈を行う場合は、複数のステートメントを {} で囲んだ方がよいでしょう。 Unix awk ブランチ構造ではネストが可能で、その形式は次のとおりです:
if(式)
{ステートメント1}
else if(式)
{ステートメント2}
else
{ステートメント3}
[チェンgmo@localhost nginx] # awk 'BEGIN{
test=100;
if(test>90)
{
print "非常に良い";
}
else if(test>60)
{
print "良い";
}
else
{
print "no pass";
}
}'
とても良い
各コマンドステートメントの後に終了できますと ";"。
2. ループ文 (while、for、do)
1. while 文
形式:
while(式(数式)
{ステートメント}
例:
[chengmo@localhost nginx]# awk 'BEGIN{
test=100;
total=0;
while(i<=test)
{
total+=i;
i++;
}
print total;
}'
5050
2.forループ
forループには2つの形式があります:
形式 1:
for(配列内の変数)
{ステートメント}
例:
[chengmo@localhost nginx]# awk 'BEGIN{
for(エンビロンのk)
{
Print k"="ENVIRON[k];
}
}'
AWKPATH=.:/usr/share/awk
OLDPWD=/home/web97
SSH_ASKPASS=/ usr/libexec/openssh/gnome-ssh-askpass
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
LANG=zh_CN.GB2312
。 。 。 。 。 。
説明: ENVIRON は awk 定数であり、準典型的な配列です。
形式 2:
for (変数; 条件; 式)
{ステートメント}
例:
[チェンモ @localhost nginx]#awk ' BEGIN{
total=0;
for(i=0;i<=100;i++)
{
total+=i;
}
print total;
}'
5050
3.doループ
形式:
do
{ステートメント}while(条件)
例:
[chengmo@localhost nginx] # awk 'BEGIN{
total=0;
i=0;
do
{
total+=i;
i++;
}while(i<=100)
print total;
} '
5050
上記はawkのフロー制御文です。構文を見るとC言語と同じであることがわかります。これらのステートメントを使用すると、多くのシェル プログラムを実際に awk に引き渡すことができ、パフォーマンスが非常に高速になります。
break Break ステートメントが while ステートメントまたは for ステートメント内で使用されると、プログラム ループが終了します。
continue continue ステートメントが while ステートメントまたは for ステートメントで使用されると、プログラムのループが次の反復に移動します。
next は、入力の次の行を読み取って、スクリプトの先頭に戻ります。これにより、現在の入力ラインで追加の操作を実行することが回避されます。
exit ステートメントは、メイン入力ループを終了させ、END が存在する場合は制御を END に移します。 END ルールが定義されていない場合、または END に exit ステートメントが適用されている場合、スクリプトの実行は終了します。
NRとFNR:
引用:
A.複数の入力ファイルに対する awk の実行シーケンスは、最初にコードが最初のファイルに適用され (行ごとに読み取られます)、次に繰り返されたコードが 2 番目のファイルに適用され、次に 3 番目のファイルに適用されます。
B. Awk による複数の入力ファイルの実行順序により、行番号の問題が発生します。最初のファイルが実行され、次に 2 番目のファイルが読み込まれるとき、2 番目のファイルの最初の行はどのように計算しますか?もう一度1として数えると、1が2つになるのではないでしょうか? (最初のファイルにも最初の行があるため)。これがNRとFNRの問題です。
NR: グローバル行番号 (2 番目のファイルの最初の行から最初のファイルの最後の行まで順番に数えられます)
FNR: 現在のファイル自体の行数 (行数と総行数は関係ありません)前の入力ファイルで))
例:data1.txt中40行、data2.txt中50行、那么awk '{}' data1.txt data2.txt
NR 的值依次次:1,2 ……40,41, 42 ... 90
FNR の値: 1, 2 ... 40, 1, 2 ... 50
Getline 関数の説明:
AWK の getline ステートメントは、単純に読み取るために使用されます。レコード。 Getline は、ユーザーが 2 つの物理レコードに似たデータ レコードを持っている場合に特に便利です。これで一般的なフィールドの分離が完了しました (フィールド変数 $0 FNR NF NR を設定)。成功した場合は 1 を返し、失敗した場合 (ファイルの終わりに達した場合) は 0 を返します。
引用:
A。 Getline 全体として、その使用法を理解する必要があります。
左右に規制方向がない場合、または & lt;(VAR または $ 0 (変数なし); AWK は Getline を処理する前に行を読み込んでいたため、Getline の戻り結果が分離されていることに注意してください。リダイレクト方向 | または & lt; または & lt; がある場合、ファイルはオープンされたばかりなので、
によって行に読み込まれます。 1 行おきではなく、ファイルの 1 行目です。 B. getline の使い方は大きく 3 つに分類できます (各大カテゴリは 2 つのサブカテゴリに分かれています)。つまり、合計 6 つの使い方があります。コードは次のとおりです。 QUOTE:nawk 'BEGIN{"cat data.txt"|getline d; print d}' data2.txt nawk 'BEGIN{"cat data.txt"|getline; }' data2 .txtnawk 'BEGIN{getline d < "data.txt"; print d}' data2.txt nawk 'BEGIN{getline < "data.txt"; 上記の 4 行のコードはすべて、「data.txt ファイルの最初の行のみを印刷する」ことを実現しています (すべての行を印刷したい場合は、ループを使用します)。 (getline<"/etc/passwd" >0){print $1}}' data.txt引用:
nawk '{getline d; print d”#”$3}' data.txt
awk は最初に最初の行を読み取り、次に getline 関数を処理し、次の行を変数 d に代入し、次に d を最初に出力します。d の後に改行文字があるため、次の # で d が上書きされ、次の $3 で上書きされます。 dも上書きします。