≡菜单

8个强大的Awk内置变量–FS,OFS,RS,ORS,NR,NF,文件名,FNR

Linux Awk教程-Awk内置变量示例This article is part of 的on-going Awk教程示例 系列。 Awk具有几个强大的内置变量。 Awk中有两种内置变量。

  1. 用于定义可以更改的值的变量,例如字段分隔符和记录分隔符。
  2. 可用于处理和报告的变量,例如记录数,字段数。

1. Awk FS 示例:输入字段分隔符变量。

默认情况下,Awk基于空格字符从输入中读取并解析每一行,并设置变量$ 1,$ 2等。AwkFS变量用于为每个记录设置字段分隔符。 Awk FS 可以设置为任何单个字符或正则表达式。您可以使用以下两个选项之一来使用输入字段分隔符:

  1. 使用-F命令行选项。
  2. 可以像普通变量一样设置Awk FS。
Syntax:

$ awk-F 'FS' 'commands' inputfilename

(or)

$ awk'BEGIN{FS="FS";}'
  • Awk FS 是要用作输入字段分隔符的任何单个字符或正则表达式。
  • Awk FS 可以多次更改,它会保留其值,直到明确更改为止。如果要更改字段分隔符,最好在阅读该行之前进行更改。因此,更改会影响您所阅读的内容。

Here is an awkFS example to read 的/etc/passwd file which has “:” as field delimiter.

$ cat etc_passwd.awk
BEGIN{
FS=":";
print " 名称 \tUserID\tGroupID\tHomeDirectory";
}
{
	print $1"\t"$3"\t"$4"\t"$6;
}
END {
	print NR,"Records Processed";
}
$awk -f etc_passwd.awk /etc/passwd
Name    UserID  GroupID         家 Directory
gnats	41	41	/var/lib/gnats
libuuid	100	101	/var/lib/libuuid
syslog	101	102	/home/syslog
hplip	103	7	/var/run/hplip
avahi	105	111	/var/run/avahi-daemon
saned	110	116	/home/saned
pulse	111	117	/var/run/pulse
gdm	112	119	/var/lib/gdm
8 Records Processed

2. Awk OFS 示例:输出字段分隔符变量

Awk OFS 是awk FS变量的输出等效项。默认情况下,awk OFS是单个空格字符。以下是awk的OFS示例。

$ awk-F':' '{print $3,$4;}' /etc/passwd
41 41
100 101
101 102
103 7
105 111
110 116
111 117
112 119

打印语句中的连接器“,”默认情况下,两个参数之间用空格连接,该空格是awk OFS的值。因此,Awk OFS值将插入到输出中的字段之间,如下所示。

$ awk-F':' 'BEGIN{OFS="=";} {print $3,$4;}' /etc/passwd
41=41
100=101
101=102
103=7
105=111
110=116
111=117
112=119

3. Awk RS 示例:记录分隔符变量

Awk RS 定义一条线。默认情况下,Awk逐行读取。

让我们以学生的分数存储在文件中为例,每个记录用双换行分隔,每个字段用换行符分隔。

$cat student.txt
Jones
2143
78
84
77

Gondrol
2321
56
58
45

RinRao
2122
38
37
65

Edwin
2537
78
67
45

Dayan
2415
30
47
20

Now 的below Awk script prints 的Student name and Rollno from 的above input file.

$cat student.awk
BEGIN {
	RS="\ n \ n";
	FS="\n";

}
{
	print $1,$2;
}

$ awk-f student.awk  student.txt
Jones 2143
Gondrol 2321
RinRao 2122
Edwin 2537
Dayan 2415

在脚本student.awk中,它将每个学生的详细信息读取为一条记录,因为awk RS已分配给双换行符,并且记录中的每一行都是一个字段,因为FS是换行符。

4. Awk ORS 示例:输出记录分隔符变量

Awk ORS is an Output equivalent of RS. Each record in 的output will be printed with this delimiter. Following is an awkORS example:

$  awk'BEGIN{ORS="=";} {print;}' student-marks
Jones 2143 78 84 77=Gondrol 2321 56 58 45=RinRao 2122 38 37 65=Edwin 2537 78 67 45=Dayan 2415 30 47 20=

In 的above script,each records in 的file student-marks file is delimited 通过 的character “=”.

5. Awk NR 示例:记录数变量

Awk NR 提供给您正在处理的记录总数或行号。在以下awk NR示例中,NR变量具有行号,在END部分中,awk NR告诉您文件中的记录总数。

$ awk'{print "Processing Record - ",NR;}END {print NR, "Students Records are processed";}' student-marks
Processing Record -  1
Processing Record -  2
Processing Record -  3
Processing Record -  4
Processing Record -  5
5 Students Records are processed

6. Awk NF 示例:记录中的字段数

Awk NF gives you 的total number of fields in a record. Awk NF will be very useful for validating whether all 的fields are exist in a record.

Let us take in 的student-marks file, Test3 score is missing for to students as shown below.

$cat student-marks
Jones 2143 78 84 77
Gondrol 2321 56 58 45
RinRao 2122 38 37
Edwin 2537 78 67 45
Dayan 2415 30 47

以下Awk脚本显示记录(行)号和该记录中的字段数。因此,很容易发现缺少Test3分数。

$ awk'{print NR,"->",NF}' student-marks
1 -> 5
2 -> 5
3 -> 4
4 -> 5
5 -> 4

7. Awk FILENAME示例: 名称 of 的current input file

FILENAME variable gives 的name of 的file being read. Awk can accept number of input files to process.

$ awk'{print FILENAME}' student-marks
student-marks
student-marks
student-marks
student-marks
student-marks

In 的above example, it prints 的FILENAME 即 student-marks for each record of 的input file.

8. Awk FNR 示例: Number of Records relative to 的current input file

When awkreads from 的multiple input file, awkNR variable will give 的total number of records relative to all 的input file. Awk FNR 将为您提供每个输入文件的记录数。

$ awk'{print FILENAME, FNR;}' student-marks bookdetails
student-marks 1
student-marks 2
student-marks 3
student-marks 4
student-marks 5
bookdetails 1
bookdetails 2
bookdetails 3
bookdetails 4
bookdetails 5

In 的above example, instead of awkFNR, if you use awkNR, for 的file bookdetails 的you will get from 6 to 10 for each record.

推荐读物

Sed和Awk 101骇客,作者:Ramesh Natarajan。我每天在UNIX / Linux环境上花费数小时来处理文本文件(数据,配置和日志文件)。我所有的文本处理工作都使用Sed和Awk。根据我在Sed和Awk的经验,’编写了Sed和Awk 101 Hacks电子书,其中包含有关Sed和Awk各种高级功能的101个实用示例,这些示例将延长UNIX / Linux的寿命。即使您已经使用Sed和Awk已有数年并且没有读过这本书,也请您帮个忙并阅读这本书。 Sed和Awk实用程序的功能会让您惊讶。

如果您喜欢这篇文章,您可能还会喜欢..

  1. 50个Linux Sysadmin教程
  2. 50个最常用的Linux命令(包括示例)
  3. 排名前25位的最佳Linux性能监视和调试工具
  4. 妈妈,我找到了! – 15个实用的Linux Find命令示例
  5. Linux 101 Hacks第二版电子书 Linux 101黑客手册

Bash 101 Hacks书 Sed和Awk 101黑客手册 Nagios Core 3书 Vim 101黑客手册

{ 38 评论 … 加一 }

  • 苛刻 2010年1月29日,下午12:23

    感谢您发布好文章。

  • 大师普拉萨德 2010年3月10日,上午10:36

    嗨拉梅什
    I tried 的example 3..but it gives 的file as is in 的output..not 符合预期..is there anything else i need to do….

  • 法兰克 2010年11月18日,晚上8:59

    去上师
    因为示例3中有错误
    线
    FS”\n”;
    应该
    FS = ”\n”;

  • 亚瑟 2010年12月13日,上午9:07

    example 3 is still not producing 的desired 的output.The output produced is 的same as 的input

  • 拉梅什·纳塔拉詹(Ramesh Natarajan) 2011年1月14日,晚上10:56

    @Frank Huang,

    感谢您指出。一世’纠正了它。仅供参考。对我来说FS”\n” and FS = ”\n” worked. I’m using GNU awk.

    $ awk--version | head -1
    GNU Awk 3.1.7
    

    @ Guru,@ Arthur,

    请使用FS =再试一次”\n”看看它是否再次起作用。如果没有,您能否让我知道您使用的是哪个版本的Awk?

  • 匿名 2011年4月7日,上午4:56

    关于awk内置变量的最佳描述。

  • 说AL_SARIRI 2011年4月11日,上午4:23

    在breif中,这个对任何人都有用的网络已经开始研究,所以我特别关注lunix的主题

  • 科林 2011年6月24日,上午3:12

    I have 的following which works fine 上 AIX but does not 上 Linux using Gawk

    回声“a:b:c” | awk‘{FS=”:”; print $2}’

    在AIX上它产生
    b
    符合预期

    在Linux上,它会产生一个空白行
    ???

    我有一个100多行的awk脚本,该脚本大量使用了FS,因此我需要能够将它从:更改为脚本中的空格到%,而不是简单地使用-F

  • he 2011年11月16日,晚上9:17

    你的博客很好
    谢谢

  • 传承人 2011年11月22日,上午8:08

    好文章
    对我有很大帮助-

  • 马努 2011年12月17日,下午11:46

    拉梅什
    仍然ex:3并没有给出预期的结果(如您的示例所示)。op仍在每个行的新行中,在字段结尾后留一个空格(在每行\ n之前)。
    我的环境是AIX 6.1(不确定awk版本)awk–版本| head -1没有给出任何结果。我什至尝试用nawk进行操作,但op并没有改变。

  • 吉姆 2012年4月5日,上午8:37

    您能帮我解决这个问题吗?这些语句本身运行良好,但我’d想将它们合并为一个。我可以’似乎无法正常工作。

    #第一句话
    egrep -w‘Deny TCP|Deny UDP’ $FW_LOG | awk‘{print $1 ” ” $2 ” ” $3}’ >> $OUTFILE

    #输出
    TCP 109.75.171.98英寸
    TCP 210.128.108.48英寸

    ===== = ===== = ===== ==

    #第二条陈述
    回声109.75.171.98 | geo
    回声210.128.108.48 | 地缘

    #输出
    日本
    英国

    我什么’d like to do is combine 的2 commands above so 的output looks like this –

    日本的TCP 109.75.171.98
    TCP 210.128.108.48在英国

    这就是我到目前为止–

    egrep -w‘Deny TCP’ IPs.txt | awk‘{cmd=”geo “$ 2; cmd | getline rslt; close(cmd);打印$ 2” “rslt}’ >> $OUTPUT

    also, 的way 地缘script works is that is accepts input – for example
    回声111.222.333.444 | geo

    没有’t seem to work like 地缘111.222.333.444 ..so maybe why it 没有’t work.

  • 匿名 2012年4月9日,下午4:30

    吉姆

    的“awk”命令具有类似于以下内容的内置模式匹配“grep”,因此您应该可以使用以下命令行执行所需的操作:(JETS)

    awk‘/Deny (UD|TC)P/{print $1,$2,$3}’ $FW_LOG >> $OUTFILE

  • 伊德 2012年4月18日,晚上10:52

    In sample 3, 的RS=”\n\n” does not work 上 my Mac terminal. Seems awkonly retrieve 的first character as Record Separator.

    但是,如果我设置RS =””(空字符串)。有用。
    我在其他情况下进行测试,似乎RS =””会使awk将多个换行符视为分隔符,就像“\n{2,}”。尽管RS不支持正则表达式。

    Maybe it is because 的version of awk?

  • 藤蔓 2012年4月27日,上午3:15

    大家好,

    你能告诉我awk(‘/开始于/ {print $ NF})server.log

    log entry is like 开始于 09m:03sec:20ms

    我想知道这里的意思是

    谢谢,
    Vineesh

  • 穆图 2012年7月27日,下午12:07

    @Vineesh
    我相信您已经找到答案了-不管怎样。
    it just searches for 的string “Started in” and when matches is found prints 的last column value.

    我喜欢这个网站-

  • 桑卡尔 2012年8月23日,上午12:33

    科林,

    这是Linux的syntex

    回声“a:b:c” | awk-F”:” ‘{ print $2}’

    要么

    回声“a:b:c” | awk‘BEGIN {FS =”:”};{ print $2}’

  • 考希克 2012年11月6日,上午1:23

    你好

    这是什么意思?

    gsub(/ [/ ^ /〜] /,” “,instring);

  • 匿名 2013年1月17日,上午5:53

    你好

    I am new to unix and can someone please explain me what 的below command does ?
    day=`cal $month $year | awk‘NF!= 0 {last = $ 0}; END {最后打印}’ | awk‘{ print $NF }’`

  • Shweta 2013年2月10日,上午11:50

    你好

    在示例3中,为什么我们使用FS =”\n”不使用这个ans还是一样…….
    我认为RS =”\n\n” is sufficient…..,请清除我的困惑……..

    预先感谢-

  • 阿兰 2013年2月21日,晚上9:17

    吉姆
    一个古老而有趣的问题。你没有’t提供输入,但看起来$ 1会是Deny,所以我以$ 2开始,但我不’没有地理位置,但如果有的话,您可能必须填写完整的路径’s another script.

    awk‘/拒绝(UD | TC)P / {printf“%s %s %s “,$2,$3,$4;cmd=”echo ” $3 “|./geo”; cmd | getline $ result; print $ result}’ $FW_LOG >> $OUTFILE

  • 西瓦 2013年4月9日,上午12:56

    @Shweta: While going through 的above docu…I also came with 的same doubt…
    注意:“Awk RS定义一行,默认情况下Awk逐行读取”…

    I share my views with 的below examples,

    =====
    例如3.1

    cat student1.txt | awk‘BEGIN{RS=”\n\n”;FS=”\n”} {打印$ 1,$ 2;} END {打印“Done”;}’
    琼斯2143
    冈多罗2321
    林劳2122
    埃德温2537
    大雁2415
    完成了

    例如3.2

    cat student1.txt | awk‘BEGIN{RS=”\n\n”} {打印$ 1,$ 2;} END {打印“Done”;}’
    琼斯2143
    冈多罗2321
    林劳2122
    埃德温2537
    大雁2415
    完成了

    例如3.3

    cat student1.txt | awk‘BEGIN{RS=”\n\n”;FS=”\n\n”} {打印$ 1,$ 2;} END {打印“Done”;}’
    琼斯
    2143
    78
    84
    77
    贡多罗
    2321
    56
    58
    45
    林劳
    2122
    38
    37
    65
    埃德温
    2537
    78
    67
    45
    大雁
    2415
    30
    47
    20
    完成了
    ===== =
    我也尝试过FS =”\n\n\n\n”, n number of times using \n inside FS, but got 的same output as 例如3.3 上 ly.

    记录始终由“\n”换行符,显然文件中的每一行都是一条记录,包括空行。这是默认设置。

    当FS是单个字符时,除了FS可能具有的值之外,换行符始终用作字段分隔符。文件中的开头和结尾的换行符将被忽略。

    因此,根据上面的示例3.1、3.2、3.3,当我们使用FS =”\n” 要么 not, we are getting 的desired output( 符合预期).

    干杯,

  • 古拉夫 2013年5月4日,下午4:44

    嗨,
    关于示例3。正如我们提到的FS =”\n” and RS=”\n\n”.RS的换行符也被视为FS字符,被视为$ 1,$ 2

    a
    b

    c
    d
    这里有两个\ n之后和b,因此它们也被FS计为字段。因此,最后$ 1 = a,$ 2 = b,$ 3和$ 4为空,$ 5 = c和$ 6 = d。

    我认为这澄清了为什么我们没有得到期望的输出。

  • 罗伊 2013年7月16日,上午6:39

    你好
    I want to separate 的fields in a file using ‘~’
    我正在使用FS =”‘~'”,但不起作用。

  • 布莱克 2013年10月17日,晚上8:56

    这实际上非常有用!
    非常感谢!!

  • 迷恋 2013年10月25日,上午1:00

    了解AWK的好页面

  • 湿婆 2013年11月11日,上午5:20

    大家好,
    我有两个文件A和B文件
    >cat A
    Empid 姓 deptid
    1 键 10
    2詹姆斯11
    > cat B
    部门名称
    10 它
    11小时

    From 的above two files, i want 的3rd file C which should contain 的output like below :-
    >cat C
    Empid 姓 deptname
    1 键 它
    2 James HR

    Please help me how to get 的bove output in unix shell scripting

  • 约瑟夫 2014年2月2日,下午5:32

    I have 2 files of 的same data, 2nd file is more recent with some values changed.
    文件一包含
    城市174,533,1,11,0,1,0,48,m ,, 1200174568,1200176241
    市,627,34,1,罗纳尔多,0,1777,0,0,m,primus,1200119084,1200120025

    文件二包含
    城市,14,153,1,11,0,1,0,485,m ,, 1200174568,1200176241
    市,627,34,1,罗纳尔多,0,1777,0,0,m,primus,1200119084,1200120025
    城市,748,332,1,janana,0,1811,0,14,m ,, 1200169533,1200171129

    文件是csv,未更新的字段是$ 0,$ 9,$ 11,$ 12,其他可以更改,我要做的是比较2个文件,搜索文件2中的$ 11,然后在文件1中查看如果它在那里,然后如果$ 1,$ 2,$ 3,$ 4,$ 5,$ 6,$ 7,$ 8或$ 10中的任何数据已更改,则将其输出到另一个文件。同样,如果文件2的记录未显示在文件1中,则也将其打印到输出文件中。

    So 的output would look like this
    城市,14,153,1,11,0,1,0,485,m ,, 1200174568,1200176241
    城市,748,332,1,janana,0,1811,0,14,m ,, 1200169533,1200171129

    查看第1行中的$ 1,$ 2和$ 8的变化
    第2行是不在文件1中的新条目

    我希望这是有道理的,在此先感谢您能为我提供帮助,这对我起到了推波助澜的作用。

  • 卡恩·古森 2014年6月16日,上午10:23

    this is very nice post. could you please explain 的below awkcode, i am never been a programmer .

    [root @ spacelab1〜]#热熔器-cu / apps01
    / apps01:859ce(oracle)882ce(oracle)1156ce(oracle)2847ce(oracle)2882ce(oracle)3034ce(oracle)3290ce(oracle)3560ce(​​oracle)6104ce(oracle)
    7663ce(oracle)8260ce(​​oracle)8312ce(oracle)8547ce(oracle)8549ce(oracle)8551ce(oracle)8555ce(oracle)8557ce(oracle)8559ce(oracle)8561ce(oracle)8563ce

    [root @ spacelab1〜]#热熔器-cu / apps01 2>/dev/null | awk‘{ for (i=1; i<=NF; i++) print $i }' | more
    859
    882
    1156
    3034
    3290
    3560
    6104

    非常感谢!

    -卡恩

  • 萨姆斯·乔治 2014年6月17日,上午2:27

    Dear All, sample 3, 的RS=”\n\n” does not work 上 my AIX box.

    问候,
    萨姆斯

  • 阿迪亚·马诺伊(Aditya Manoj) 2014年7月18日,上午2:40

    亲爱的湿婆,
    This is 的solution for your query. This is may not be 的apt solution. But i put my efforts to get it. This is working fine.
    grep -i“bond” a | awk‘BEGIN {print “empid”,”empname”}{print $1,”\t”,$2}’ >> aa
    猫咪
    Empid 姓
    1 键

    grep -i“it” b | awk‘BEGIN {print “DEPTNAME”}{print $2}’ >>bb
    猫bb
    部门名称

    awk‘NR == FNR {_ [NR] = $ 0; next} {打印$ 1,$ 2,_ [FNR]}’ bb aa
    Empid 姓 部门名称
    1 键 它

  • 阿迪亚·马诺伊(Aditya Manoj) 2014年7月18日,上午2:42

    Thank you 湿婆 for posting such a query. This query is similar to 的pl/sql query.

  • 普拉布 2014年8月7日,上午12:37

    如何使用AWK从文件中删除特定行….

    例如:在下面的情况下,我的输入如下所示(我想删除特定的一行):我的案例行号:3将被删除
    输入样例:

    “Unix是多任务和多用户系统
    Unix是开源的
    Unix包含许多命令
    Unix是我最喜欢的主题”

    所以我想低于输出

    “Unix是多任务和多用户系统
    Unix是开源的
    Unix是我最喜欢的主题”

  • 陈天伟 2015年1月10日,下午1:02

    An awkone 线 r can do 的job for 湿婆 .

    awk‘开始{while(getline< "b"){arr [$ 1] = $ 2}} {打印$ 1,$ 2,arr [$ 3]}' a
    Empid 姓 deptname
    1 键 它
    2 James HR
    3约翰·恩德

    首先将文件b读取到BEGIN块中的awk关联数组arr [$ 1] = $ 2中。这将成为您对主程序的查找表,该表从文件a,$ 1 $ 2和arr [$ 3]而不是$ 3打印。
    awk可以打开另一个文件b,并使用getline读取每一行,并在从文件a读取之前填充数组arr。您可以添加close("b"),以获取良好的编程习惯。

  • 米杜尔 2016年2月16日,上午1:03

    你好
    我有一个CDR文件,其中的字段由‘|’每行是一个cdr。有些cdr有54个字段,有些则有41个字段。
    i want to get 上 ly 的cdrs with 41 fields.
    I can count 的lines with number of filed value with below command but can not find 的lines themselves. Can you please help
    zcat push.cdr.20160216.105825.gz | awk-F‘|’ ‘{print NF}’|sort -r |uniq -c

  • 陈天伟 2016年2月17日,上午1:09

    zcat x.gz | awk-F’|’ ‘NF==41′
    -F’|’ will reset 的field separator FS variable in to fields delimited 通过 的pipe.
    Then, use NF == 41 as 的awk pattern/condition to print 上 通过 default.
    要打印特定字段,您可以使用
    zcat x.gz | awk-F’|’ ‘NF == 41 {打印$ 1 $ 2}’ # where $1 and $2 are 的fields you want printed.
    Awk将从zcat命令的输出中读取解压缩的文件,并使用管道作为分隔符将行一一拆分,并将字段数自动分配给NF。只要满足条件NF == 41,它将默认打印输出行。如果您指定带有特定字段变量的print命令,在这种情况下分别是第一个和第二个变量$ 1和$ 2,则将打印第一和第二列。

  • 戈帕尔 2016年2月23日,上午4:10

    示例3正在为我工​​作,如下所示…

    #猫student.awk
    开始 {
    RS = “”;
    FS = “\n”;

    }
    {
    print $1,$2;
    }

    #awk -f student.awk student.txt
    琼斯2143
    冈多罗2321
    林劳2122
    埃德温2537
    大雁2415

    这里

  • 普里扬卡·辛格(Priyanka Singh) 2017年3月31日,上午4:51

    Hands down 的best article 上 awkvariables I’ve come across…Keep up 的good work !!!

发表评论