shell和awk之间传递参数
来源:互联网 发布:linux 两台机器复制 编辑:程序博客网 时间:2024/06/15 01:47
Awk怎么引入变量?
有两种方法:
<1>: awk -v var=$VAR '{code}'
<2>: awk '{CODE}'$VAR'{CODE}'
例如:
- VAR=XXX
- awk -v var=$VAR 'BEGIN{print var}'
- XXX
- awk 'BEGIN{print "'$VAR'"}'
- XXX
我推荐使用第一种方法,这样可以避免一些不必要的烦恼。如http://bbs.chinaunix.net/thread-1835620-1-1.html
http://blog.csdn.net/sosodream/article/details/5746315
awk与shell间参数(或说变量传递)是shell编程中常有的话题了,因为其中实际涉及到不少的知识点,比如包括
a:进程进通信
b:awk参数形式
c:shell命令解析,命令替换
等等,在此列举二三点例子,做为小结。以下主要分为二部分
1:shell给awk传参
2:awk往shell传参
参考文档:gnu 的awk documentation
http://www.gnu.org/software/gawk/manual/gawk.html#Language-History
===================================
第一部分,shell往awk传参
首先得理解下awk的二种变量,和三种参数(变量)附值形式
二种变量,这里指内部变量,和自定义变量(本文先不讨论awk的函数局部变量,后续有空补上)
和shell一样,awk也有一些内置的变量,如NR,NF等,变量的赋值了有各自的规则(不再展开,具体看awk文档各变量说明)
自定义变量,通常是为程序需要自身定义的变量,不具有像内置变量那样的作用。
这二类变量的附值,实际上并没多少差别,只是文档中有提到,对内置变量的附值,有可能会得到不期望的结果,有些是被接收的,有些是不被接受的(原文:Caution: Using-v to set the values of the built-in variables may lead to surprising results.awk will reset the values of those variables as it needs to, possibly ignoring any predefined value you may have given.)
awk三种变量附值形式:
1:-v var=text
特点,一次一附值一次,作用在BEGIN模块之前,命令行位置必需要文件类参数之前,可以更改内置变量,不收录ARGV
常用于传shell变量给awk
2:BEGIN模块
特点:awk程序体进行的变量附值 ,其中BEGIN模块的执行在读输入之前,可以更改内置变量
典型的用法是在没输入的时候运行一段awk程序就写在begin里
3:无-v的var=text形式
特点:可以更改内置变量,类同文件类参数,收录进ARGV,放在文件类参数前,在文件类参数对应文件开始读入前起作用
参考以上例子:
例子一:
root@rac0 tmp]# cat -n a1;cat -n b1;cat -n a.awk
1 1 aa 5
2 1 bbb 55
3 1 ccc 555
1 2 a
2 2 b
3 2 c
1
2 BEGIN {
3
4 printf "in begin ,n=%d/n", n;
5 for (i = 0; i < ARGC; i++)
6 printf "/tARGV[%d] = %s/n", i, ARGV[i]
7 }
8 {print n,$n}
9 END { printf "in end n=%d/n", n; }
[root@rac0 tmp]# awk -f a.awk -v n=1 n=3 a1 n=2 b1
in begin ,n=1
ARGV[0] = awk
ARGV[1] = n=3
ARGV[2] = a1
ARGV[3] = n=2
ARGV[4] = b1
3 5
3 55
3 555
2 a
2 b
2 c
in end n=2
看点:
1:-v,-f等option参数,不列入ARGV
2:-v的参数,要求在文件类参数(包括不加-v的var=text)之前
3:-v的效果,在BEGIN之前
4:n=3,n=2的效果
例子二:
比如要用awk计算某些单词在某些文件(列可能不同)出现个数,除了在程序里指定列,还可以在命令行里进行指定,简单而清晰
[root@rac0 tmp]# cat words1
fqef word4
wfww word3
[root@rac0 tmp]# cat words2
word4 aaa
word2 fwww
word1 fwwww
[root@rac0 tmp]# awk '{a[$n]++}END{for(b in a)print b,a[b]}' n=2 words1 n=1 words2
word1 1
word2 1
word3 1
word4 2
===================
第二部分,awk传参数给shell
这个就涉及到进程间通信了,因为shell调用起来的awk实际的执行环境是shell脚本运行进程的一个子进程,子进程原则上除了继承到自身环境上的变量外,无法对父进程的环境进行访问和修改的,所以在awk里执行system()变量附值,也更也不了shell参数
那么,如何做?
之前在cu上有讨论过函数调用的变量附值 ,回帖粘过来,不再展开了呵
(函数对shell变量更改)通常可以用这么几个办法
1:用全局变量附值(这种方法不适用于awk,下边有描述)
var=
func(){ var=blabla; };
func
2:用命令替换附值
func(){ echo blabla; };
var=$(func)
3:eval
(注,在这个例子中倒显得有点烦索,其实eval一个经典的用法就是用来脚本之间传递参数用的,毕竟进程间环境无法相互涉及)
var=
fun(){ echo "var=blabla";};
cmd=$(fun)
eval $cmd
echo $var
4:ipc...
unix系最常用的ipc莫过于管道
func(){ echo "var=blabla" }
func | read line
eval $line
下边有个例子,是以前以前用过的一个例子,用的是命名管道
[oracle@rac2 tmp]$ cat -n test.sh
1
2
3 mkfifo t;
4
5 a=0;
6 b=0;
7 awk 'BEGIN{print "a=1;b=2";print "end";}' >t &
8
9 while read c
10 do
11 test "$c" == "end" && break;
12 eval $c
13 done <t
14
15 echo $a,$b;
16
17 rm t
注一:以上函数调用时增加参数不影响使用
注二:除了第一个方法:全局变量外,另外三种方法其实也广泛用到其他函数(如awk)更改shell变量值的应用上,因为subshell所在的子进程并不能更改到父进程的环境表,更改全局变量在这种情况下没效果。
读取变量
在通过如下方式读取Shell变量
1> awk -v varName=varValue '...' ...
2> awk '...{print "'"${USER}"'"}' ...
此种方式可以访问系统环境变量(如USER等),和自定义Shell变量。若这些变量中没有空格及其他特殊字符,则可以少写两个双引号:awk '...{print "'${USER}"}' ...
3> awk '...{print ENVIRON["USER"]}...' ...
但是这种方法只能访问系统变量
设置变量
在AWK中尚未找到设置Shell变量的方法,因为像上面的读取的方法中,一旦awk开始执行,这些环境变量都是一个副本,无论处理多少条记录,不管主Shell中如何变化,所引用的这些变量值都保持不变。而且,通过下面的实验可以看出来,在AWK中执行system函数调用命令是另起一个Shell线程,所以无法依靠system来设置外部环境变量。
如果你的AWK只打印一条结果的话,可以使用如下方式在shell环境中设置变量
myVar="`echo | awk '{print "AA\nBB\nCC"}'`"
注意,这种方式在awk打印多行情况下会将回车用空格替代后赋值。
实验过程如下:
$ vi tmp.sh
// 编辑内容如下
#!/bin/bash
echo
echo "SHELL VERSION : ${SHELL} ${BASH_VERSION}"
echo "AWK VERSION : `awk -W version | sed -n '1p'`"
echo
myVar="AAA BBB CCC DDD"
echo "IN SHELL : PID=$$"
echo "IN SHELL : \${myVar}=\"${myVar}\""
echo
echo | awk -v var1="${myVar}"'{
print "IN AWK : how to print single quote : " "'"'"'"
print "No." NR
print "IN AWK : -v : var1=\"" var1 "\""
print "IN AWK : get : ENVIRON[\"USER\"]=\"" ENVIRON["USER"] "\""
print "IN AWK : get : ENVIRON[\"myVar\"]=\"" ENVIRON["myVar"] "\""
print "IN AWK : get : ${USER} =\"" "'"${USER}"'" "\""
print "IN AWK : get : ${myVar}=\"" "'"${myVar}"'" "\""
print
system("echo \"IN AWK : system() : PID=$$\"")
}'
myVar="`echo | awk '{print "AA\nBB\nCC"}'`"
#\n is replaced by space character
echo ${myVar}
$ . tmp.sh
//输出结果如下
SHELL VERSION : /bin/bash 3.2.25(1)-release
AWK VERSION : GNU Awk 3.1.5
IN SHELL : PID=10627
IN SHELL : ${myVar}="AAA BBB CCC DDD"
IN AWK : how to print single quote:'
No.1
IN AWK : -v : var1="AAA BBB CCC DDD"
IN AWK : get : ENVIRON["USER"]="zhangll"
IN AWK : get : ENVIRON["myVar"]=""
IN AWK : get : ${USER} ="zhangll"
IN AWK : get : ${myVar}="AAA BBB CCC DDD"
IN AWK : system(): PID=17468
AA BB CC
- shell和awk之间传递参数
- shell和awk之间互传参数
- [Linux] awk与shell参数传递
- [awk]awk 与 shell的参数传递(双向)
- awk与shell之间的变量互相传递方法
- awk与shell之间的变量传递方法
- shell awk 变量传递
- shell 传递参数和数组
- sed awk 传递参数
- sed awk 传递参数
- awk 传递参数
- 向awk传递参数
- linux入门之awk和shell变量传递
- awk与shell参数传递(或说变量传递)二三点
- awk与shell参数传递(或说变量传递)二三点
- shell & awk 变量传递+awk综合概要
- 信号和槽之间的传递参数
- struts和jsp页面之间传递参数
- BIT 1010 Maximum Sum
- apache与nginx上传目录无执行权限的解决办法
- c语言典型例题及代码(1)
- gson(JSON字符串转换成一个相等的Java对象)
- BIT 1013 Bone Collector
- shell和awk之间传递参数
- Android中自定义控件
- c语言典型例题及代码(2)
- Git往远程push前修改commit信息
- mysql主从库不同步的解决方法
- HTML5
- BIT 1014 Big Event in BIT
- NYOJ 485 A*B Problem
- POJ 3749 破译密码