awk 子进程 父进程 交互

本文介绍了awk如何读取shell变量,以及awk中的输出重定向和调用shell命令的方法。awk通过-v选项读取shell变量,输出重定向可用于传递变量值。同时,awk能通过管道调用shell命令,awk的BEGIN和END块可以使用-v传入的变量。此外,还展示了主进程如何获取子进程awk的输出值以及awk调用主进程shell变量的方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

(3)awk读取shell中的变量

可以使用-v选项实现功能
     b=1 b=1cat f
     apple

?
1
$awk -v var =$b '{print var, $var}' file

1 apple
至于有没有办法把awk中的变量传给shell呢,这个问题我是这样理解的。shell调用awk实际上是fork一个子进程出来,而子进程是无法向父进程传递变量的,除非用重定向(包括管道)
a= (awkprint$b,$bf) (awk′print$b,′$b′′f)echo $a
apple 1

(4)输出重定向 , awk是子进程,如何传出awk中的变量值

awk的输出重定向类似于shell的重定向。重定向的目标文件名必须用双引号引用起来。
awk awk′4 >=70 {print 1, 1,2 > "destfile" }' filename
awk awk′4 >=70 {print 1, 1,2 >> "destfile" }' filename

(5)awk中调用shell命令:

1)使用管道
awk中的管道概念和shell的管道类似,都是使用"|"符号。如果在awk程序中打开了管道,必须先关闭该管道才能打开另一个管道。也就是说一次只能打开一个管道。shell命令必须被双引号引用起来。“如果打算再次在awk程序中使用某个文件或管道进行读写,则可能要先关闭程序,因为其中的管道会保持打开状态直至脚本运行结束。注意,管道一旦被打开,就会保持打开状态直至awk退出。因此END块中的语句也会收到管道的影响。(可以在END的第一行关闭管道)”
awk中使用管道有两种语法,分别是:
awk output | shell input
shell output | awk input

对于awk output | shell input来说,shell接收awk的输出,并进行处理。需要注意的是,awk的output是先缓存在pipe中,等输出完毕后再调用shell命令 处理,shell命令只处理一次,而且处理的时机是“awk程序结束时,或者管道关闭时(需要显式的关闭管道)”

?
1
$awk  '/west/{count++}  {printf "%s %s\t\t%-15s\n", $3,$4,$1 | "sort +1"}  END{close "sort +1"; printf "The number of sales pers in the western"; printf "region is " count "." }' datafile

(解释:/west/{count++}表示与“wes”t进行匹配,若匹配,则count自增)
printf函数用于将输出格式化并发送给管道。所有输出集齐后,被一同发送给sort命令。必须用与打开时完全相同的命令来关闭管道(sort +1),否则END块中的语句将与前面的输出一起被排序。此处的sort命令只执行一次。

在shell output | awk input中awk的input只能是getline函数。shell执行的结果缓存于pipe中,再传送给awk处理,如果有多行数据,awk的getline命令可能调用多次。
$awk 'BEGIN{ while(("ls" | getline d) > 0) print d}' file

 

(6)主进程直接获取子进程awk的输出值:

     1. var=· shell_cmd | awk ' print $1 '

      2.var=$(shell_cmd | awk ' print $1 ') ·

      3.eval
       (注,在这个例子中倒显得有点烦索,其实eval一个经典的用法就是用来脚本之间传递参数用的,毕竟进程间环境无法相互涉及)
       var=
       fun(){ echo "var=blabla";};
       cmd=$(fun)
       eval $cmd
       echo $var

 

(7)子进程awk调用主进程shell的变量 

1、获得普通外部变量

[ chengmo @ localhost ~ ] $ test = 'awk code'
[ chengmo @ localhost ~ ] $ echo | awk '{print test}' test = "$test"
awk code
[ chengmo @ localhost ~ ] $ echo | awk test = "$test" '{print test}'
awk : cmd . line : 1 : fatal : cannot open file ` { print test }' for reading ( No such file or directory )

 

[chengmo@ localhost ~]$ echo | awk ‘BEGIN{print test}’ test=”$test”

这种变量在:BEGIN的action不能获得。

 

2.BEGIN程序块中变量

2
3
4
5
[ chengmo @ localhost ~ ] $ test = 'awk code'
[ chengmo @ localhost ~ ] $ echo | awk - v test = "$test" 'BEGIN{print test}'
awk code
[ chengmo @ localhost ~ ] $ echo | awk - v test = "$test" '{print test}'
awk code

 

格式如:awk –v 变量名=变量值 [–v 变量2=值2 …] ‘BEGIN{action}’ 注意:用-v 传入变量可以在3中类型的action 中都可以获得到,但顺序在 action前面。

3.获得环境变量

 

1
2
3
4
5
6
7
[ chengmo @ localhost ~ ] $ awk 'BEGIN{for (i in ENVIRON) {print i"="ENVIRON[i];}}'
AWKPATH = . : / usr / share / awk
SSH_ASKPASS = / usr / libexec / openssh / gnome - ssh - askpass
SELINUX_LEVEL_REQUESTED =
SELINUX_ROLE_REQUESTED =
LANG = en_US .UTF - 8
. . . . . . .

只需要调用:awk内置变量 ENVIRON,就可以直接获得环境变量。它是一个字典数组。环境变量名 就是它的键值。

 

4.直接使用shell变量。
格式如下:awk '{print "'$shell_var'"}' filename,注意:先用双引号,再用单引号。

  1. #!/bin/sh 
  2.   
  3. var="test" 
  4.   
  5. awk ' 
  6. BEGIN{ 
  7.     print "begin outputvar:" "'$var'" 
  8.     print "'$var'" 
  9. END{ 
  10.     print "end outputvar:" "'$var'" 
  11. } ' group_file3

 

 

5. 内部函数

  5.1  字符串替换

          sub(/regrexp/,"REPLACEMENT",target) target省略就是$0 , 可以是$1 $2 .. $10, 正则表达式要有/ / , REPLACEMENT 要有 “ ”

          gsub( /regrexp/,"REPLACEMENT",target)   (regular expression, substitution string)

          gensub(regexp, replacement, “how”, target) 这个事gawk提供的一个通用型的函数,返回替换后的字符串。上两个返回替换的数目。

          gensub确实不同于sub和gsub这2个工具,它有它更独特的魅力,下面我通过几个例子给大家讲解它的实际用法和独到之处。

  1. echo "11111" | awk 'BEGIN{FS=OFS=""}{$4="x";print}'
  2. 111x1
[解析]
  这个时候阁下是不是看这段没有字段分割符的文本已经感到无从下手了?呵呵,经过这一系列的FS、OFS设置我们终于达到了目的,是不是很麻烦?我们再看看下面的例子。
 
  1. echo "11111" | awk '{print $0=gensub("1","x",4)}'
    111x1

echo "11111" | awk '{print $0=gensub("1","x","g")}'

xxxxx

[解析]

  阁下是不是豁然开朗了很多?这就是gensub的便捷,在这里面不再需要字段分割符,用数字即可指定你要替换的某一位。g和G是指全局替换,要双引号标记起来。特别注意的是gensub是不会修改原记录的,所以要对$0进行一个赋值。“the modified string is returned as the result of the function and the original target string is not changed”。接下来我们再看看一个更复杂的运用。

 

  1. echo "unix linux" | awk '{print gensub(/(.+) (.+)/,"\\2 \\1","g")}'
    linux unix

  1. echo "xaax xbx xxx:xaax xbx xxx" | awk -F: -vOFS=":" '{$2=gensub(/x([^x]+)x/,"\\1YY",2,$2)}1'
    xaax xbx xxx:xaax bYY xxx

[解析]

  是不是觉得很眼熟?呵呵是的,就是sed的用法,对!还有正则。特别注意的是需要双斜杠噢。聪明的您以后一定会熟练gensub的用法的 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值