(Translated by https://www.hiragana.jp/)
AWK - 维基百科,自由的百科全书 とべ转到内容ないよう

AWK

本页使用了标题或全文手工转换
维基百科ひゃっか自由じゆうてき百科ひゃっかぜん
AWK
编程范型脚本きゃくほん过程しきかずすえ驱动[1][2]
設計せっけいしゃおもね尔佛かみなりとく·もぐさこうかれとく·ぬるはくかく以及ぬの萊恩·柯林かん
发行时间1977ねん
とうぜん版本はんぽん
  • IEEE Std 1003.1-2008
編輯維基數據鏈接
かたたい系統けいとう无;支持しじくし整数せいすう浮点すう,以及せい则表达式
操作そうさけいまたが平台ひらだい
あみcm.bell-labs.com/cm/cs/awkbook/index.html
主要しゅようさく產品さんぴん
awk, GNU Awk, mawk, nawk, MKS AWK, Thompson AWK(编译), Awka(编译
衍生ふくかたりげん
old awk oawk 1977, new awk nawk 1985, GNU Awk gawk
啟發けいはつげん
C, Sed, SNOBOL[1][2]
影響えいきょうげん
Tcl, AMPL, Perl

AWKいち种优りょうてきぶんほん处理工具こうぐLinuxUnix环境ちゅう现有てきこうのう最强さいきょうだいてきかずすえ处理引擎いち。这种编程及数すえ操作そうさ语言(其名たたえ于它てき创始じんおもね尔佛かみなりとく·もぐさこうかれとく·ぬるはくかくぬの萊恩·柯林かん姓氏せいしてきくび个字ははてき最大さいだいこう能取のとろ决于一个人所拥有的知识。AWK提供ていきょうりょう极其强大きょうだいてきこうのう以进行正ゆきまさ则表达式てきひきはい,样式そういれながれひかえせい数学すうがく运算、进程ひかえせい语句甚至于内おけてき变量函数かんすう。它具备了一个完整的语言所应具有的几乎所有精美特性。实际じょうAWKてき确拥ゆう自己じこてき语言:AWKほどじょ设计语言,三位创建者已将它正式定义为“样式扫描处理语言”。它允许创けん简短てきほどじょ,这些ほどじょ读取输入ぶんけん、为数すえはいじょ、处理すうすえ、对输にゅう执行计算以及生成せいせい报表,还有无数其他てきこうのう。gawkAWKてきGNU版本はんぽん

さい简单说,AWK一种用于处理文本的编程语言工具。AWKざい很多方面ほうめん类似于Unix shell编程语言,つきかんAWK具有ぐゆう完全かんぜんぞく于其本身ほんみてき语法。它的设计思想しそうらいげんSNOBOL4sed、Marc Rochkind设计てき有效ゆうこうせい语言、语言工具こうぐyacclex当然とうぜん还从C语言ちゅう获取りょういち些优しゅうてき思想しそうざい最初さいしょ创造AWK时,其目的もくてきよう于文ほん处理,并且这种语言てきもと础是,ただようざい输入すうすえ中有ちゅううしきひきはい,就执ぎょういち系列けいれつ指令しれい。该实よう工具こうぐ扫描ぶんけんちゅうてきごといちぎょう,查找与命令めいれいぎょうちゅうしょ给定内容ないようしょうひきはいてきしき。如果发现ひきはい内容ないよう,则进ぎょう一个编程步骤。如果找不いたひきはい内容ないよう,则继续处いちぎょう

AWKほどじょ结构

[编辑]

AWK一种处理文本文件的语言。它将ぶんけんさく为记录序列じょれつ处理。ざい一般いっぱんじょう况下,ぶんけん内容ないようてきごとあるきいち个记录。まい行内こうないよう都会とかい分割ぶんかつなりいち系列けいれつてきいきいん此,わが们可以认为一行的第一个词为第一个域,だい二个词为第二个,以此类推。AWKほどじょよし一些处理特定模式的语句块构成的。AWK一次可以读取一个输入行。对每个输入行にゅうこう,AWKかい释器かい判断はんだん它是符合ふごうほどついで中出なかいで现的かく个模しき,并执ぎょう符合ふごうてきしきしょ对应てき动作。

——おもね尔佛かみなりとく·もぐさこうThe A-Z of Programming Languages: AWK

AWKほどじょよしいち系列けいれつしき--动作对组なりてきうつし

pattern { action }

其中pattern表示ひょうじAWKざいすうすえちゅう查找てき内容ないよう,而actionざい找到ひきはい内容ないよう时所执行てきいち系列けいれつ命令めいれい。输入行にゅうこうぶんなりりょういち些记录:记录默认由换行分割ぶんかついん此输入会にゅうかい按照ぎょう进行分割ぶんかつほどじょ使用しよう给定てき条件じょうけん一个个的测试每条记录,并执ぎょう测试どおり过的条件じょうけんしょ对应てきactionpatternaction省略しょうりゃくうつし。无patternだま认匹はい全部ぜんぶてき记录;而无action则是しるし原始げんし记录。简单てきAWKひょう达式そとpattern以是BEGINあるEND;这两种条件じょうけん对应てきactionぶん别是读取所有しょゆうてき记录ぜん和之かずゆききさきどう时,如pattern1, pattern2てき条件じょうけん表示ひょうじ符合ふごう条件じょうけんpattern1pattern2てき记录及其间的部分ぶぶん

じょりょう一般いっぱんてきC语言风格てきさん术和逻辑运算がい,AWKまこと许运さん~もちいらい测试せい则表达式いや以与一字符串匹配。さく语法とうぼつゆう~运算てきせい则表达式かいもちいらい对当ぜん记录进行测试,相当そうとう/regexp/ ~ $0

AWK命令めいれい

[编辑]

AWK命令めいれいそく为前文例ぶんれい子中こなかactionゆびだいてき语句。AWK命令めいれい包括ほうかつ函数かんすう调用,变量赋值,计算,及/あるかく项的组合。标准AWK提供ていきょうりょう许多ないけん函数かんすう;其部分ぶぶん实现则可能かのう提供ていきょうりょうさらてきないけん函数かんすうどう时,AWKてき部分ぶぶん实现支持しじ动态链接库使つかいとく其可以支持しじさらてき函数かんすう便利べんりおこり见,しもじゅつれい子中こなか可能かのう省略しょうりゃくだいくくごう{ })。

print命令めいれい

[编辑]

print 命令めいれいよう于输ぶんほん。其输てきぶんほん总是以"输出记录ぶんへだた"(Output record separator, ORS)分割ぶんかつてき,其默认值为换ぎょう。该命令めいれいてきさい简形しき为:

print
かい输出とうぜん记录てき内容ないようざいAWKちゅう,记录かい分割ぶんかつなりいき”,它们以被ぶん别显しめせある使用しよう
print $1
显示とうぜん记录てきだい1个域
print $1, $3
显示とうぜん记录てきだい1だい3个域,并以预定义的输出いきぶんへだた(Output field separator, OFS)ぶんへだた,其默认值为一个空かく

虽然いきてき符号ふごう($X )可能かのう类似于某些语ごとちゅうてき变量(れいPHPperl),ただしざいAWKちゅう,它们ゆびだいてきとうぜん记录てきいき。另外,$0ゆびせい个记录。こと实上,命令めいれいprintprint $0てき效果こうかしょうどうてきprint命令めいれい也可以显しめせ变量、计算、函数かんすう调用てき结果:

print 3+2
print foobar(3)
print foobar(variable)
print sin(3-2)

其输以重ていこういたFile:

print "expression" > "file name"

ある重定しげさだこういたかんどう

print "expression" | "command"

うちけん变量

[编辑]

AWKてきないけん变量包括ほうかついき变量,れい如$1, $2, $3,以及$0。这些变量给出りょう记录ちゅういきてき内容ないよううちけん变量也包括ほうかついち些其变量:

  • NR:やめ输入记录てきじょうすう
  • NF:とうぜん记录ちゅういきてき个数。记录ちゅうさいきさきいち个域以以$NFてき方式ほうしき引用いんよう
  • FILENAME:とうぜん输入ぶんけんてきぶん件名けんめい
  • FS:“いきぶんへだた”,よう于将输入记录分割ぶんかつなりいき。其默认值为“空白くうはく”,そくそら格和かくわせいひょう。FS以替换为其它,从而あらため变域ぶんへだた
  • RS:とうまえてき“记录ぶんへだた”。だま认状态下,输入てきごとあるきさく为一个记录,いん此默认记录分へだた换行
  • OFS:“输出いきぶんへだた”,そくぶんへだたprint命令めいれいてきまいりすうてき符号ふごう。其默认值为空かく
  • ORS:“输出记录ぶんへだた”,そくまいprint命令めいれい间的符号ふごう。其默认值为换ぎょう
  • OFMT:“输出数字すうじ格式かくしき”(Format for numeric output),其默认值为"%.6g"。

变量语法

[编辑]

变量めい以是语言关键外的がいてきただ包含ほうがん大小だいしょううつしひしげ丁字ていじはは数字すうじ划线(“_”)てき任意にんい。而操作そうさ“+ - * /”则分别代表だいひょう,减,じょうじょ。简单てきはた两个变量(あるくしつねりょうざい一起かずき,则会しょうしゃくしせっ为一个字くしわか二者间至少有一个是常量,则中间可以不そらかくただしわかしゃひとし为变りょうちゅう间必须包括ほうかつそらかくくしつねりょう以双引号(“"”)ぶんへだたてき。语句无需以分ごう结尾。另外,ちゅう释是以“#”开头てき

よう户定义函すう

[编辑]

函数かんすう以与C语言类似てき方式ほうしきてい义的,以关键字function开头,きさきめん跟函すう名称めいしょうまいり数列すうれつひょう函数かんすうたい

# しめせれい函数かんすう
function add_three (number) {
  return number + 3
}

上面うわつらてき函数かんすう以如此调よう

print add_three(36)     # 输出39

函数かんすう以拥ゆう私有しゆう变量。其私有しゆう变量以写ざいさん数列すうれつひょうきさきいん为这些值かいざい调用函数かんすう时被ゆるがせりゃく通常つうじょう以在さん数列すうれつひょうちゅうさんすう私有しゆう变量加入かにゅういち些空かくよう以区别“真正しんせいてきさんすう私有しゆう变量。 函数かんすう声明せいめいちゅう函数かんすう名和なわくくごう间可以有任意にんいそらかくただしざい调用时二しゃ必须紧邻。

样例ほどじょ

[编辑]

Hello World

[编辑]

AWKてきhello worldほどじょ为:

BEGIN { print "Hello, world!" }

注意ちゅうい此处无需うつしexit语句,いん为唯いちてきしきBEGIN

输出长度だい于80てきぎょう

[编辑]

输出长度だい于80てきぎょう注意ちゅういしきてきだま认行为是输出とうまえぎょう

length($0) > 80

输出单词计数

[编辑]

对输いれちゅうてき单词进行计数,しかきさき输出ぎょうすう,单词すう和字わじすう(类似wc)。

{
    w += NF
    c += length + 1
}
END { print NR, w, c }

よし于没ゆう提供ていきょうしき,输入てき全部ぜんぶあるき以匹はい该模しきいん此对ごとぎょう都会とかい执行预定操作そうさ注意ちゅういw+=NFてき含义とうどうw = w + NF

计算さいきさき一个单词的和

[编辑]
{ s += $NF }
END { print s + 0 }

sすう$NFてき累加るいか$NFごとじょう记录ちゅうてきさいきさきいち个域,NFぼつゆう$)とうまえぎょうちゅういきてき数量すうりょうれい如一个域数为4てきぎょうちゅう$NF相当そうとう$4こと实上,$いち具有ぐゆう最高さいこう优先级てき一元いちげん运算。(わかいちぎょうぼつゆういき,则有NF为0,而$NF相当そうとう$0せいぎょうざい这种じょう况下,よう么是そらくしよう么只ゆう空白くうはくいん此其すう值为0。)

ぶんけん结束时,ENDしきいたりょうひきはいいん此可以输sしか而,ざいぼつゆう入行にゅうこうてきじょう况下,sかいぼつゆう值,从而导致ぼつゆう输出。よし此,对其0以使AWKざい这种じょう况下对其赋值,从而いたいち个数值。这种方法ほうほうはたくし强制きょうせい转化为数值的惯用ほうはんこれあずかむなしくし连接则是しょうすう强制きょうせい转换为字くしてき方法ほうほうれいs "")。如此处理きさきわかほどじょ输入为空文くうぶんけん以得いた“0”さく为输,而不いち空行くうぎょう

ひきはい入行にゅうこうちゅうてき范围

[编辑]
$ yes Wikipedia | awk 'NR % 4 == 1, NR % 4 == 3 { printf "%6d  %s\n", NR, $0 }' | sed 7q
     1  Wikipedia
     2  Wikipedia
     3  Wikipedia
     5  Wikipedia
     6  Wikipedia
     7  Wikipedia
     9  Wikipedia
$

yes命令めいれいじゅう复输にゅう其参すうだま认则输出“y”)。ざい这里,わが们让该命令めいれい输出“Wikipedia”。动作块则输出带行ごうてき内容ないようprintf函数かんすう以模拟标じゅんCなかてきprintf函数かんすう,其效果こうかあずか前述ぜんじゅつてきprint函数かんすう类似。而符合ふごうしきてきぎょう这样产生てきNR记录てき编号,也就AWKただしざい处理ぎょうてきぎょうごう(从1开始)。“%”これすう操作そうさよし此,NR % 4 == 1对第1,5,9とうぎょう为真。类似てきNR % 4 == 3对3,7,11とうぎょう为真。范围しきざい其第いち部分ぶぶんひきはいれい如对だい1ぎょうぜん为假,并在だい部分ぶぶんひきはいれい如第3ぎょうぜん为真。しかきさきさいざいだい二次匹配上其第一部分(れい如第5ぎょうぜん为假。sed命令めいれい则是よう于截取其前7ぎょう输出,防止ぼうしyes命令めいれい一直运行下去。わかhead命令めいれい可用かようてき话,这行命令めいれいてき效果こうかhead -n7あいどうわか范围しきてきだい一部分永远为真,れい如设てい为“1”,以用らい使つかい该范围从输入てきさい开始开始。类似てきわかだい二部分总是为假,れい如“0”,则该范围てき结束そく为输いれてき结束。 命令めいれい

/^--cut here--$/, 0

かい输出从符合ふごうせい则表达式“^--cut here--$”开始てき入行にゅうこう,也即从只包含ほうがん“--cut here--”てきぎょう开始,ちょくいた输入てき结束。

计算词频

[编辑]

使用しよう关联すう计算词频:

BEGIN {
    FS="[^a-zA-Z]+"
}
{
     for(i=1; i<=NF; ++i)
          words[tolower($i)]++
}
END {
    for(i in words)
         print i, words[i]
}

BEGIN块设ていいきぶんへだた任意にんい字母じぼ。值得注意ちゅういてきふんへだた仅可以是くし,也可以是正ぜせい则表达式。しかきさきほどじょ对每个输入行にゅうこう执行しょうどうてき操作そうさざい此,对每个域,わが累加るいか其小うつし形式けいしき现的次数じすうさいきさきざいEND块中,わが们输单词及其现的次数じすうだい

for(i in words)

建立こんりゅうりょう一个遍历关联数组中元素的循环,其中,iかい设为对应てき键。这一点和多数语言不同,而和Objective-C 2.0なかてきfor...in语法相似そうじ。这样てき语法まこと许以简单てき方式ほうしきへん历数组,从而输出这些单词。另外,tolower函数かんすうOne True awk(见下ぶんてき附加ふか函数かんすう

从命れいひきはいしき

[编辑]

这个ほどじょ以以种不どう形式けいしき现。だいいち使用しようBourne shellあし本来ほんらい完成かんせいだい部分ぶぶん工作こうさく。这也最短さいたんてきいち个方ほう

$ cat grepinawk
pattern=$1
shift
awk '/'$pattern'/ { print FILENAME ":" $0 }' $*
$

awk命令めいれいちゅうてき$pattern并没ゆう为引ごうしょ护。ざい这里,しき以检查输入行にゅうこう$0いなあずかこれひきはいFILENAME变量则包含ほうがんりょうとうまえてきぶん件名けんめい。awkぼつゆう显式てきくし连接操作そうさあずかBASH相似そうじただ需简单的はたくし并列そく$0则会输出原始げんしてき入行にゅうこう也有やゆう另外てき方法ほうほうらい完成かんせいどう样的にん务。下面かめんてき脚本きゃくほん直接ちょくせつざいawkちゅう访问环境变量

$ cat grepinawk
pattern=$1
shift
awk '$0 ~ ENVIRON["pattern"] { print FILENAME ":" $0 }' $*
$

这个脚本きゃくほんよういたりょうすうENVIRONいち个One True awkちゅう引入てきりょう。其作よう类似あずかPOSIX标准ちゅうてきgetenv (3)函数かんすう。这个脚本きゃくほんさき建立こんりゅうりょういち个名为patternてき环境变量,其值为脚本きゃくほんてきだいいち个参すうしかきさき让awkざい其余てきまいりすうしょ代表だいひょうてきぶんけんない寻找该模しき~よう于检查其两个操作そうさすうひきはいてき运算;其逆则为!~注意ちゅういせい则表达式也属于普どおりてきくし以储そん于变りょうちゅう下面かめんてき方法ほうほう则采ようりょうざい命令めいれいぎょう对变りょう赋值てき方法ほうほうそくざいawkてきさんすうちゅううつしいれいち个变量的りょうてき值:

$ cat grepinawk
pattern=$1
shift
awk '$0 ~ pattern { print FILENAME ":" $0 }' "pattern=$pattern" $*
$

さいきさき,这种方法ほうほう纯awkてき,无需shellてき帮助,也无需知どうふとし关于awk脚本きゃくほん实现てき细节(而在命令めいれいぎょう对变りょう赋值てき方法ほうほう可能かのうあずかawkてき实现しょう关);ただし这种方法ほうほうてきあし本有ほんゆうてん长:

BEGIN {
    pattern = ARGV[1]
    for (i = 1; i < ARGC; i++) # じょだいいち个参すう
        ARGV[i] = ARGV[i + 1]
    ARGC—if (ARGC == 1) { # しき唯一ゆいいつさんすういん强制きょうせい从标じゅん输入读取
        ARGC = 2
        ARGV[1] = "-"
    }
}
$0 ~ pattern { print FILENAME ":" $0 }

BEGIN块的作用さよう仅仅つつみ取出とりでだいいち个参すう,也防止ぼうしだいいち个参すうざいBEGIN块结たばきさき直接ちょくせつかい释为输入ぶんけんARGC,输入さんすうてき数量すうりょうなが远是しょう于1てきいんARGV[0]执行脚本きゃくほんてき命令めいれいめい通常つうじょう"awk"。另外,ARGV[ARGC]えい远是そらくし。对于其中てきif块,它表明ひょうめいわかぼつゆう指定してい输入ぶんけん,awkかい直接ちょくせつ读取标准输入りゅうstdin)。也即

awk 'prog'

也可以工作こうさくいん为程じょちゅうやめ经将ARGCおけ为了2;わか该值为1,则awkかい认为ぼつゆうぶんけん需要じゅよう读取而直接ちょくせつ退出たいしゅつどう时,わか需从标准输入读取すうすえ需要じゅよう将文まさふみ件名けんめい显式てき指定してい-

包含ほうがんてきAWK脚本きゃくほん

[编辑]

あずか许多其他てきほどじょ语言相似そうじ利用りようshebang”语法构建包含ほうがんてきawk脚本きゃくほんれい如,いち个名为hello.awk以输“Hello, world!”てきUNIX命令めいれい以通过建立こんりゅう内容ないよう如下,めいhello.awkてきぶんけんらい完成かんせい

#!/usr/bin/awk -f
BEGIN { print "Hello, world!" }

-fまいりすうつげ诉awkはた该文けんさく为awkてきほど序文じょぶんけんしかきさきそく运行该程じょ

まいり

[编辑]


参考さんこう文献ぶんけん

[编辑]
  1. ^ 1.0 1.1 Andreas J. Pilavakis. UNIX Workshop. Macmillan International Higher Education. 1989: 196. 
  2. ^ 2.0 2.1 Arnold Robbins. Effective Awk Programming: Universal Text Processing and Pattern Matching 4th. O'Reilly Media. 2015: 560. 

外部がいぶ链接

[编辑]