【awk】1-awk基础篇(又名UNIX.She…

2023-10-11 16:38
文章标签 基础 awk unix 又名

本文主要是介绍【awk】1-awk基础篇(又名UNIX.She…,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

转自:http://bkeep.blog.163.com/blog/static/1234142902010425110453/

导读:

1awk基本语法

2,比较操作符

3,复合表达式

4next命令

5,变量及变量赋值

6awk中的赋值操作符

7BEGINEND

8,内置变量 

9awk使用shell变量

10awk中的三种流控制语句

10.1 if语句

10.2 while语句:

10.3 for语句:

11,实验:

12shell里的特殊变量

 

正文:

 

1awk基本语法

awk ‘script’  files

script 由下面的结构组成 /pattern/{actions}

例子:打印fruit_prices.txt文件的内容

[root@master bkeep]# awk '{print;}' fruit_prices.txt

fruit           price/lbs               quantity

banana          $0.89                   100

peach           $0.79                   65

kiwi            $1.50                   22

pineapple       $1.29                   35

apple           $0.99                   78

 

TIPS:留意printf的用法 如果加“-”说明是左对齐!

 

[root@master bkeep]# awk '{printf "%-15s %s\n", $1, $3;}' fruit_prices.txt

fruit           quantity

banana          100

peach           65

kiwi            22

pineapple       35

apple           78

 

留意printf的用法 如果不加“-”说明是右对齐!

[root@master bkeep]# awk '{printf "s %s\n", $1, $3;}' fruit_prices.txt

          fruit quantity

         banana 100

          peach 65

           kiwi 22

      pineapple 35

          apple 78

 

例子:给价格高于1美元的水果加个星号

[root@master bkeep]# cat fruit_prices.txt

fruit           price/lbs               quantity

banana          $0.89                   100

peach           $0.79                   65

kiwi            $1.50                   22

pineapple       $1.29                   35

apple           $0.99                   78

[root@master bkeep]# cat price.sh

#!/bin/bash

awk '

   / *\$[1-9][0-9]*\.[0-9][0-9] */ {print $1,$2,$3,"*";} //星号前面一定要留空格,否则匹配不到

   / *\$0\.[0-9][0-9] */ {print;}       //以后养成习惯,/ key /斜杠和key之间始终留空格

' fruit_prices.txt

执行结果:

[root@master bkeep]# ./price.sh

banana          $0.89                   100

peach           $0.79                   65

kiwi $1.50 22 *

pineapple $1.29 35 *

apple           $0.99                   78

上面的格式很不好看,我们改改它吧!

TIPS$0awk使用变量0原原本本地存储它所读入的整个输入行。这样可以保持和原来文本格式相同的输出

[root@master bkeep]# cat price.sh        

#!/bin/bash

awk '

   / *\$[1-9][0-9]*\.[0-9][0-9] */ {print $0,"*";}

   / *\$0\.[0-9][0-9] */ {print;}

' fruit_prices.txt

[root@master bkeep]# ./price.sh

banana          $0.89                   100

peach           $0.79                   65

kiwi            $1.50                   22 *

pineapple       $1.29                   35 *

apple           $0.99                   78

2,比较操作符

语法:expression {actions;}

expression 可以使用以下操作符构成

<                                 小于

>                                 大于

<=                               小于等于

>=                               大于等于

==                               等于

!=                               不等于

value ~ /pattern/          value匹配pattern则为真

value !~ /pattern/         value不匹配pattern则为真

说明:$2 ~ /^\$[1-9][0-9]*  将匹配第二列以$开头,然后大于1的二位数。(注意,这里是1而不是10

 

例子:给数量大于50的水果加星号

[root@master bkeep]# cat larger.sh

#!/bin/bash

awk '

    $3>50 {printf "%s\t%s\n", $0,"*"}

    $3<=50 {printf "%s\n",$0}

' fruit_prices.txt

[root@master bkeep]# ./larger.sh

fruit           price/lbs               quantity        *

banana          $0.89                   100     *

peach           $0.79                   65      *

kiwi            $1.50                   22

pineapple       $1.29                   35

apple           $0.99                   78      *

3,复合表达式

语法:(compound expression

expr1&& (expr2)  -------

expr1|| (expr2)  -------

说明一下:符合表达式必须用括号括起来

当使用&&时,expr1expr2必须同时为零(零代表真!呵呵~),复合表达式才为真;

当使用 || 时,expr1expr2 只要有一个为真,复合表达式则为真!

 

例子:显示价格高于1美元且数量少于50的水果记录,给打个标记!

[root@master bkeep]# cat larger.sh

#!/bin/bash

awk '

 ($2 ~ /^\$[1-9][0-9]*\.[0-9][0-9]$/) && ($3<50) {  //这是一个模式匹配(请参阅比较操作符

 printf "%s\t%s\t%s\n", $0,"*","reorder";

}

' fruit_prices.txt

[root@master bkeep]# ./larger.sh

kiwi            $1.50                   22      *       reorder

pineapple        $1.29                   35      *       reorder

4next命令

例子:给库存少于50的水果价格标签!

[root@master bkeep]# cat next.sh

#!/bin/bash

awk '

   $3 <= 50 { printf "%s\t%s\n",$0,"REORDER" ; }

   $3 > 50 {print $0; }

' fruit_prices.txt

 

当输入行为:kiwi    $1.50      22

脚本执行以下过程:

1)检查是否第三列的值22小于50,由于值小于50,执行脚本的第二步

2)打印该行,并在行尾添加REORDER标志

3)检查是否第三列的值22大于50,由于值不大于50,脚本读下一行

呵呵,傻子都看得出这种情况下执行第三步是多余的。那么如何跳过呢?可以使用next命令。

next命令:告诉awk跳过剩下的所有模式和表达式,并读取输入的下一行,同时从第一个模式或表达式开始处理该行!

 

修改后的脚本,加入了next命令!

[root@master bkeep]# cat next.sh

#!/bin/bash

awk '

   $3 <= 50 { printf "%s\t%s\n",$0,"REORDER" ;next; }

   $3 > 50 {print $0; }

' fruit_prices.txt

[root@master bkeep]# ./next.sh

fruit           price/lbs               quantity

banana          $0.89                   100

peach           $0.79                   65

kiwi            $1.50                   22      REORDER

pineapple       $1.29                   35      REORDER

apple           $0.99                   78

 

现在脚本执行如下;

1)检查是否第三列的值22小于50,由于值小于50,所以执行脚本第二步

2)打印输出行并在该行后打印REORDER标志有了next后就不再执行$3 > 50 {print $0; }

3)读取下一输入行并从第一种模式开始

5,变量及变量赋值

下面给变量赋值

fruit=100   //把数字赋给fruit变量

fruit=”peach”  //把字符串赋给fruit变量

fruit=$1      //把第一列赋给fruit变量

 

awk中的数字操作符:

+           

-            

*           

/            

%           求余

^            求幂

 

应用例子:统计文件中的空行数

[root@master bkeep]# cat for.sh

#!/bin/bash

for i in $@;    //这里我们不知道有多少个文件需要统计,所以用$@来接收参数!

do

   if [ -f $i ]; then

      echo $i

      awk ' /^$/ { x=x+1;} END{print x;}' $i

    else

      echo "ERROR:$i not a file." >&2

    fi

done

[root@master bkeep]# ./for.sh aa bb

aa                  //文件名为aa

7                   //空行数7

bb                  //文件名为bb

4                   //空行数为4

6awk中的赋值操作符

+=                 x+=1 就是x=x+1

-=                  x-=1 就是x=x-1

*=                 x*=1 就是x=x*1

/=                  x/=1 就是x=x/1

%=                x%=2 就是x=x%2

^=                 x^=2 就是x=x^2

 

7BEGINEND

awk的语法:/pattern/ {action}    pattern:模式

这里pattern有两个特殊模式BEGINEND

下面是BEGIN  END的语法:

awk ‘

BEGIN { actions }

/ pattern / { actions }

/ pattern / { actions }

END { actions }

  files

 

BEGINEND都是可选的

·当指定BEGIN模式时,awk在读取任何输入前执行动作 actions

·当指定END模式时,awk在其退出前执行动作actions

 

这里要特别注意:比如awk读入aa.txt。那么BEGIN只在读入aa时执行一次,然后按行处理的时候不再执行BEGIN指定的action!(也可以这么理解:BEGIN只对文件生效,而不是按行生效!!);理解了BEGINEND还会糊涂吗?呵呵!

8,内置变量

gawk语言中有几个十分有用的内置变量,现在列于下面:

NR 已经读取过的记录数。

FNR 从当前文件中读出的记录数。

FILENAME 输入文件的名字。

FS 字段分隔符(缺省为空格)。

RS 记录分隔符(缺省为换行)。

OFMT 数字的输出格式(缺省为% g)。

OFS 输出字段分隔符。

ORS 输出记录分隔符。

NF 当前记录中的字段数。

如果你只处理一个文件,则NR FNR 的值是一样的。但如果是多个文件, NR是对所有的文件来说的,而FNR 则只是针对当前文件而言。

 

例子:统计空行的脚本:

[root@master bkeep]# cat for.sh

#!/bin/bash

for i in $@;

do

   if [ -f $i ]; then

#      echo $i

      awk 'BEGIN { printf "%s\t",FILENAME;}   //输出文件名

         /^$/ { x+=1;}                    //统计空行

       END{avg=100*(x/NR); printf "%s\t%3.1f\n",x,avg;}' $i   //最后算百分比及打印结果

    else

      echo "ERROR:$i not a file." >&2

    fi

done

[root@master bkeep]# ./for.sh aa bb  //显示出来的结果很漂亮。可惜了,文件名没出来

        7       87.5                      //怀疑FILENAME内置变量被修改了???

        4       57.1

9awk使用shell变量

经过前面的学习,我们知道shell变量的引用由$xxx 实现,而awk中的变量直接使用xxx来引用。所以我们就要思考如何让awk使用shell变量

语法:

awk  ‘script’  awkvar1=value  awkvar2=value ......  files

说明: awk 命令; script’:awk将要执行的脚本; awkvarNawk的变量;valueshell中的变量值; files:将要处理的文件名

 

【重点实验记忆】

例子:根据用户提供的水果数量,将低于这个值的水果打印出来!

[root@master bkeep]# cat awk_var.sh

#!/bin/bash

NUM_FRUIT="$1"       //将用户输入传递给shell变量NUM_FRUIT

if [ -z "$NUM_FRUIT" ]; then NUM_FRUIT=75;fi  //如果用户没有输入,则赋默认值75

awk '

    $3 <= num_fruit {print;}      //最终将用户输入传递给awk变量num_fruit

'   num_fruit="$NUM_FRUIT"  fruit_prices.txt   //通过此方法将$NUM_FRUIT

//赋值给num_fruit;即把shell变量赋给awk

执行结果:

[root@master bkeep]# ./awk_var.sh 40        //将数量低于40的水果打印出来

kiwi            $1.50                   22

pineapple       $1.29                   35

[root@master bkeep]# ./awk_var.sh 30     //将数量低于30的水果打印出来

kiwi            $1.50                   22

10awk中的三种流控制语句

if语句

while语句

for语句

10.1 if语句

if (expression1) {action1}

else if (expression2) {action2}

else { action3}

执行过程:

1)计算expression1的值

2)若expression1为真,执行action1并推出if语句

3)若expression1为假,计算expression2

4)若expression2为真,执行action2并退出if语句

5)若expression2为假,执行action3并退出if

 

举例:若水果价格高于1美元,那么给它加星号;若水果数量少于50,则给它加REORDER

[root@master bkeep]# cat reorder.sh

#!/bin/bash

awk '{

   printf "%s\t",$0;

   if ( $2 ~ /\$[1-9][0-9]*\.[0-9][0-9]/ ) {

        printf " * ";

        if ($3 <= 75) {

        printf "REORDER\n";

        } else {

           printf "\n";

        }

   }else {

        if ($3<=75) {

        printf "REORDER\n";

        }else {

              printf "\n";

        }

   }

}' fruit_prices.txt

执行结果:

[root@master bkeep]# ./reorder.sh

fruit           price/lbs               quantity

banana          $0.89                   100

peach           $0.79                   65      REORDER

kiwi            $1.50                   22       * REORDER

pineapple       $1.29                   35       * REORDER

apple           $0.99                   78

10.2 while语句:

while (expression) { actions }

expression为真,则执行actions

[root@master bkeep]# awk 'BEGIN { x=0;while(x<3) {x+=1;print x;}}'   //先给x+1再输出

1

2

3

[root@master bkeep]# awk 'BEGIN { x=0;while(x<3) {print x;x++}}'   //先输出再给x+1

0

1

2

 

Tipsdo语句是while语句衍生出来的;区别在于do至少执行一次,while有可能不执行

10.3 for语句:

for initialize_counter; test_counter;increment_counter {

     action

}

解释一下,呵呵

for (初始化计数器变量;测试计数器是否到顶了;增加计数器的值)  {

   要执行的动作!

}

 

【常用】例子:循环迭代处理记录中的域并输出他们

[root@master bkeep]# cat for2.sh

#!/bin/bash

awk '{

    for (x=1;x<=NF;x+=1) {

      printf "%s    ",$x "zbb";

    }

    printf "\n";

}' fruit_prices.txt

 

[root@master bkeep]# ./for2.sh

fruitzbb    price/lbszbb    quantityzbb   

bananazbb    $0.89zbb    100zbb   

peachzbb    $0.79zbb    65zbb   

 

根据输出我们重点理解下awkfor循环的执行过程

1)读取一行数据

2)执行for循环,处理每一个字段,将其输出,退出for循环

3)执行第二个action即输出一个换行符

4)重复13,直到处理完所有行!

11,实验:

例子:倒序显示记录中的每个行

方法一:用for实现

#!/bin/bash

awk '

{a[NR]=$0};         //第一个action:把记录存储在一个数组里面

END{for (x=NR;x>0;x-=1) {              //第二个actionfor循环,x=NR总行数

       printf "%s\n",a[x];          //如果x>0,则x=x-1,倒序输出a[x]数组中的内容!

       }

}' fruit_prices.txt   //要处理的文件名!

 

方法2:用while实现

#!/bin/bash

awk '

{line[NR] = $0 }   //把所有记录都存放到数组里面

END {var=NR      //把总行数赋给变量var

while (var > 0){   //var大于0时,执行后面的action

print line[var]

var--                            //var=var-1

}}

' fruit_prices.txt    //文件名

执行结果:

[root@master bkeep]# ./re.sh

apple           $0.99                   78

pineapple       $1.29                   35

kiwi            $1.50                   22

peach           $0.79                   65

banana          $0.89                   100

fruit           price/lbs               quantity

12shell里的特殊变量

# sh /usr/local/bkeep/shell.sh 001 002

I'm $0 is:/usr/local/bkeep/shell.sh         //正在被执行脚本的名字;`basename $0`

I'm $1 is:001                 //$1接收到的参数

I'm $2 is:002                 //$2接收到的参数

I'm $# is:2                    //总共接收到的参数个数

I'm $* is:001 002          //把接收到的参数全部打印出来

I'm $@ is:001 002         //同上

I'm $? is:0                    //上一个脚本的退出状态“0代表正常;“1非正常退出

I'm $$ is:24137             //当前执行脚本的进程ID

I'm $! is:                      //前一个后台进程的id

 

例子:再进一步解释下$*$@吧;仔细看下面的例子,我就不废话了!

[root@master bkeep]# cat shell.sh

#!/bin/bash

cc=$*

echo "I'm \$1 is:$1"

echo "I'm \$2 is:$2"

echo "I'm \$* is:$*"

echo "I'm \$4 is:$4"

[root@master bkeep]# ./shell.sh 11 22 33 "44" 55

I'm $1 is:11

I'm $2 is:22

I'm $* is:11 22 33 44 55

I'm $4 is:44

应用例子:统计文件中的空行数

[root@master bkeep]# cat for.sh

#!/bin/bash

for i in $@;    //这里我们不知道有多少个文件需要统计,所以用$@来接收参数!

do

   if [ -f $i ]; then

      echo $i

      awk ' /^$/ { x=x+1;} END{print x;}' $i

    else

      echo "ERROR:$i not a file." >&2

    fi

done

[root@master bkeep]# ./for.sh aa bb

aa                  //文件名为aa

7                   //空行数7

bb                  //文件名为bb

4                   //空行数为4

这篇关于【awk】1-awk基础篇(又名UNIX.She…的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/189396

相关文章

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型的操作流程

《0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeekR1模型的操作流程》DeepSeekR1模型凭借其强大的自然语言处理能力,在未来具有广阔的应用前景,有望在多个领域发... 目录0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型,3步搞定一个应

MySQL中my.ini文件的基础配置和优化配置方式

《MySQL中my.ini文件的基础配置和优化配置方式》文章讨论了数据库异步同步的优化思路,包括三个主要方面:幂等性、时序和延迟,作者还分享了MySQL配置文件的优化经验,并鼓励读者提供支持... 目录mysql my.ini文件的配置和优化配置优化思路MySQL配置文件优化总结MySQL my.ini文件

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

AI基础 L9 Local Search II 局部搜索

Local Beam search 对于当前的所有k个状态,生成它们的所有可能后继状态。 检查生成的后继状态中是否有任何状态是解决方案。 如果所有后继状态都不是解决方案,则从所有后继状态中选择k个最佳状态。 当达到预设的迭代次数或满足某个终止条件时,算法停止。 — Choose k successors randomly, biased towards good ones — Close

音视频入门基础:WAV专题(10)——FFmpeg源码中计算WAV音频文件每个packet的pts、dts的实现

一、引言 从文章《音视频入门基础:WAV专题(6)——通过FFprobe显示WAV音频文件每个数据包的信息》中我们可以知道,通过FFprobe命令可以打印WAV音频文件每个packet(也称为数据包或多媒体包)的信息,这些信息包含该packet的pts、dts: 打印出来的“pts”实际是AVPacket结构体中的成员变量pts,是以AVStream->time_base为单位的显

C 语言基础之数组

文章目录 什么是数组数组变量的声明多维数组 什么是数组 数组,顾名思义,就是一组数。 假如班上有 30 个同学,让你编程统计每个人的分数,求最高分、最低分、平均分等。如果不知道数组,你只能这样写代码: int ZhangSan_score = 95;int LiSi_score = 90;......int LiuDong_score = 100;int Zhou

c++基础版

c++基础版 Windows环境搭建第一个C++程序c++程序运行原理注释常亮字面常亮符号常亮 变量数据类型整型实型常量类型确定char类型字符串布尔类型 控制台输入随机数产生枚举定义数组数组便利 指针基础野指针空指针指针运算动态内存分配 结构体结构体默认值结构体数组结构体指针结构体指针数组函数无返回值函数和void类型地址传递函数传递数组 引用函数引用传参返回指针的正确写法函数返回数组

【QT】基础入门学习

文章目录 浅析Qt应用程序的主函数使用qDebug()函数常用快捷键Qt 编码风格信号槽连接模型实现方案 信号和槽的工作机制Qt对象树机制 浅析Qt应用程序的主函数 #include "mywindow.h"#include <QApplication>// 程序的入口int main(int argc, char *argv[]){// argc是命令行参数个数,argv是

【MRI基础】TR 和 TE 时间概念

重复时间 (TR) 磁共振成像 (MRI) 中的 TR(重复时间,repetition time)是施加于同一切片的连续脉冲序列之间的时间间隔。具体而言,TR 是施加一个 RF(射频)脉冲与施加下一个 RF 脉冲之间的持续时间。TR 以毫秒 (ms) 为单位,主要控制后续脉冲之前的纵向弛豫程度(T1 弛豫),使其成为显著影响 MRI 中的图像对比度和信号特性的重要参数。 回声时间 (TE)