tcltk awk中调用shell awk,awk 的 $2 不识别

新手园地& & & 硬件问题Linux系统管理Linux网络问题Linux环境编程Linux桌面系统国产LinuxBSD& & & BSD文档中心AIX& & & 新手入门& & & AIX文档中心& & & 资源下载& & & Power高级应用& & & IBM存储AS400Solaris& & & Solaris文档中心HP-UX& & & HP文档中心SCO UNIX& & & SCO文档中心互操作专区IRIXTru64 UNIXMac OS X门户网站运维集群和高可用服务器应用监控和防护虚拟化技术架构设计行业应用和管理服务器及硬件技术& & & 服务器资源下载云计算& & & 云计算文档中心& & & 云计算业界& & & 云计算资源下载存储备份& & & 存储文档中心& & & 存储业界& & & 存储资源下载& & & Symantec技术交流区安全技术网络技术& & & 网络技术文档中心C/C++& & & GUI编程& & & Functional编程内核源码& & & 内核问题移动开发& & & 移动开发技术资料ShellPerlJava& & & Java文档中心PHP& & & php文档中心Python& & & Python文档中心RubyCPU与编译器嵌入式开发驱动开发Web开发VoIP开发技术MySQL& & & MySQL文档中心SybaseOraclePostgreSQLDB2Informix数据仓库与数据挖掘NoSQL技术IT业界新闻与评论IT职业生涯& & & 猎头招聘IT图书与评论& & & CU技术图书大系& & & Linux书友会二手交易下载共享Linux文档专区IT培训与认证& & & 培训交流& & & 认证培训清茶斋投资理财运动地带快乐数码摄影& & & 摄影器材& & & 摄影比赛专区IT爱车族旅游天下站务交流版主会议室博客SNS站务交流区CU活动专区& & & Power活动专区& & & 拍卖交流区频道交流区
UID空间积分0 积分15阅读权限10帖子精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
白手起家, 积分 15, 距离下一级还需 185 积分
帖子主题精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
论坛徽章:0
例如有shell函数:
function add1()
& && & result=`expr $1 + 1`
& && & echo $result
export -f add1
awk 'BEGIN{&add1 2&|print result }'& && & #这里输出3,因为我传了2作为参数
但是我想要把2赋给变量,例如 p=2,再通过p作为参数传递给add1,如果调用呢?
&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp&&nbsp|&&nbsp
UID空间积分0 积分3155阅读权限50帖子精华可用积分3155 信誉积分567 专家积分0 在线时间762 小时注册时间最后登录
小富即安, 积分 3155, 距离下一级还需 1845 积分
帖子主题精华可用积分3155 信誉积分567 专家积分0 在线时间762 小时注册时间最后登录
论坛徽章:14
UID空间积分0 积分15阅读权限10帖子精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
白手起家, 积分 15, 距离下一级还需 185 积分
帖子主题精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
论坛徽章:0
songyc_2015
这个帖子里,没有用参数变量传递,只是传的值,我之前已经看过了~谢谢
UID空间积分860 积分49091阅读权限100帖子精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
帖子主题精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
认证徽章论坛徽章:80
function add1()
{
& && & result=`expr $1 + 1`
& && & echo $result
}
export -f add1
awk 'BEGIN{p=3;&add1 &p|print result }'复制代码
【图书免费赠送】
【Windows批处理】
UID空间积分0 积分15阅读权限10帖子精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
白手起家, 积分 15, 距离下一级还需 185 积分
帖子主题精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
论坛徽章:0
function add1()
& && & result=`expr $1 + $2 + 1`
& && & echo $result
灰常感谢~如果是两个参数呢?
export -f add1
awk 'BEGIN{p=3;q=4;&add1 &p q|print result }'&&这样好像不行?小白求指教
UID空间积分860 积分49091阅读权限100帖子精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
帖子主题精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
认证徽章论坛徽章:80
justcx function add1()
{
& && & result=`expr $1 + $2 + 1`
& && & echo $result
}
export -f add1
awk 'BEGIN{p=3;q=4;&add1 &p& &q|print result }'复制代码
【图书免费赠送】
【Windows批处理】
UID空间积分0 积分15阅读权限10帖子精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
白手起家, 积分 15, 距离下一级还需 185 积分
帖子主题精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
论坛徽章:0
& & 传单参数的也执行不了~继续求指导~麻烦你运行下看看
UID空间积分860 积分49091阅读权限100帖子精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
帖子主题精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
认证徽章论坛徽章:80
看什么地方?
[root]# ./test.sh
[root]# cat test.sh
function add1()
& && & result=`expr $1 + 1`
& && & echo $result
export -f add1
awk 'BEGIN{p=3;&add1 &p|print result }'
【图书免费赠送】
【Windows批处理】
UID空间积分0 积分15阅读权限10帖子精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
白手起家, 积分 15, 距离下一级还需 185 积分
帖子主题精华可用积分15 信誉积分22 专家积分0 在线时间11 小时注册时间最后登录
论坛徽章:0
10:54 上传
10:54 上传
不知道怎么回事,跟你一样的,就是运行出错~
UID空间积分860 积分49091阅读权限100帖子精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
帖子主题精华可用积分39091 信誉积分3559 专家积分105 在线时间12149 小时注册时间最后登录
认证徽章论坛徽章:80
1、改成 #!/bin/bash 可以吗?
2、你用的什么系统?我的是 RHEL 6.5
【图书免费赠送】
【Windows批处理】
北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:
广播电视节目制作经营许可证(京) 字第1234号
中国互联网协会会员&&联系我们:
感谢所有关心和支持过ChinaUnix的朋友们
转载本站内容请注明原作者名及出处awk命令详解&(转&整理)
awk有3个不同版本:
awk、nawk和gawk,未作特别说明,一般指gawk。awk语言的最基本功能是在文件或字符串中基于指定规则来分解抽取信息,也可以基于指定的规则来输出数据。完整的awk脚本通常用来格式化文本文件中的信息。
二、基本语法
awk [opion] 'awk_script'
input_file1 [input_file2 ...]
awk的常用选项option有:
①&-F
使用fs作为输入记录的字段分隔符,如果省略该选项,awk使用环境变量IFS的值
②&-f
filename&: 从文件filename中读取awk_script
③&-v
var=value&: 为awk_script设置变量
awk有三种运行方式:
第一种,把awk的脚本命令直接放在命令中。
第二种,把awk的所有的脚本命令放在一个脚本文件中,然后用-f选项来指定要运行的脚本命令文件。
第三种,将awk_script放入脚本文件并以&#!/bin/awk
-f&作为首行,给予该脚本可执行权限,然后在shell下通过键入该脚本的脚本名调用之。
三、awk脚本
awk脚本可以由一条或多条awk_cmd组成,对于多个awk_cmd,一个awk_cmd完成后,应该另起一行,以便进行隔。&
awk_cmd由两部分组成:&awk_pattern
{ actions }。
另外,在awk命令中直接使用awk_script时,awk_script也可以被分成多行书写,但必须确保整个awk_script被单引号括起来。
awk命令的一般形式:
awk '&BEGIN&{
awk_pattern1 { actions
............
awk_patternN { actions
END&{ actions
' inputfile
其中 BEGIN { actions } 和 END { actions
} 是可选的。
在awk脚本中可以使用AWK本身内置变量,如下:&
ARGC&命令行变元个数
ARGV&命令行变元数组
FILENAME&当前输入文件名
FNR&当前文件中的记录号
FS&输入域分隔符,默认为一个空格
RS&输入记录分隔符
NF&当前记录里域个数
NR&到目前为止记录数
OFS&输出域分隔符
ORS&输出记录分隔符
awk脚本的运行过程:
①&如果BEGIN&区块存在,awk执行它指定的actions。
②&awk从输入文件中读取一行,称为一条输入记录。(如果输入文件省略,将从标准输入读取)
③&awk将读入的记录分割成字段,将第1个字段放入变量$1中,第2个字段放入$2,以此类推。$0表示整条记录。字段分隔符使用shell环境变量IFS或由参数指定。
④&把当前输入记录依次与每一个awk_cmd中awk_pattern比较,看是否匹配,如果相匹配,就执行对应的actions。如果不匹配,就跳过对应的actions,直到比较完所有的awk_cmd。
⑤&当一条输入记录比较了所有的awk_cmd后,awk读取输入的下一行,继续重复步骤③和④,这个过程一直持续,直到awk读取到文件尾。
⑥&当awk读完所有的输入行后,如果存在END,就执行相应的actions。
1)input_file可以是多于一个文件的文件列表,awk将按顺序处理列表中的每个文件。
2)一条awk_cmd的awk_pattern可以省略,省略时不对输入记录进行匹配比较就执行相应的actions。一条awk_cmd的actions
也可以省略,省略时默认的动作为打印当前输入记录,即{print $0}
。一条awk_cmd中的awk_pattern和actions不能同时省略。
3)&BEGIN区块和END区块别位于awk_script的开头和结尾。awk_script中只有END区块或者只有BEGIN区块是被允许的。如果awk_script中只有BEGIN
{ actions } ,awk不会读取input_file。
4)&awk把输入文件的数据读入内存,然后操作内存中的输入数据副本,awk不会修改输入文件的内容。
5)&awk的总是输出到标准输出,如果想让awk输出到文件,可以使用重定向。
3.1.awk_pattern
awk_pattern模式部分决定actions动作部分何时触发及触发actions。
awk_pattern可以是以下几种类型:
1)&正则表达式用作awk_pattern:&/regexp/
注意,正则表达式regexp必须被/包起来
awk中正则表达式匹配操作中经常用到的字符:
\ ^ $ . [] | () *
//&:通用的regexp元字符
匹配其前的单个字符一次以上,是awk自有的元字符,不适用于grep或sed等
匹配其前的单个字符1次或0次,是awk自有的元字符,不适用于grep或sed等
关于正则表达式的更多内容请参《》
awk '/&*\$0\.[0-9][0-9].*/'
input_file
比如,行内容为$0.99.
helllo的行就可以和上面的正则表达式相配
2)&布尔表达式用作awk_pattern,表达式成立时,触发相应的actions执行。
①&表达式中可以使用变量(如字段变量$1,$2等)和/regexp/
②&布尔表达式中的操作符:
关系操作符:&&
& &= &= ==
匹配操作符:&value&~&/regexp/&如果value匹配/regexp/,则返回真
value&!~&/regexp/&如果value不匹配/regexp/,则返回真
{print "ok"}' input_file
'$3&~&/^d/&{print
"ok"}' input_file
③&&&(与)
可以连接两个/regexp/或者布尔表达式,构成混合表达式。!(非)
可以用于布尔表达式或者/regexp/之前。
'($1 & 10 ) && ($2
& 10) {print $0 "ok"}' input_file
awk '/^d/&||&/x$/&{print
$0 "ok"}' input_file
④&其它表达式用作awk_script,如赋值表达式等
'(tot+=$6); END{print "total points :" tot }'
input_file&//
分号不能省略
awk 'tot+=$6 {print $0}
END{print "total points :" tot }' input_file&//
与上面等效
当使用赋值表达式时,表示如果赋值后的变量是数字的话,如果为非0,就匹配,否则不匹配;如果为字符串的话,非空就为匹配,否则不匹配。
awk内置字符串函数:
gsub(r,s) &
& 在整个$0中用s替代r
awk 'gsub(/name/,"xingming") {print $0}'
gsub(r,s,t) &
在整个t中用s替代r
index(s,t) &
&返回s中字符串t的第一位置
awk 'BEGIN {print index("Sunny","ny")}'
temp & & 返回4
length(s) &
& 返回s的长度
match(s,r) &
&测试s是否包含匹配r的字符串
awk '$1=="J.Lulu" {print match($1,"u")}'
temp & &返回4
split(s,a,fs) &
& & 在fs上将s分成序列a
awk 'BEGIN {print
split("12#345#6789",myarray,"#")"'
返回3,同时myarray[1]="12", myarray[2]="345",
myarray[3]="6789"
sprint(fmt,exp) &
& 返回经fmt格式化后的exp
sub(r,s) &
从$0中最左边最长的子串中用s代替r(只更换第一遇到的匹配字符串)
substr(s,p) &
返回字符串s中从p开始的后缀部分
substr(s,p,n) &
返回字符串s中从p开始长度为n的后缀部分
awk字符串连接操作&
[chengmo@centos5 ~]$ awk 'BEGIN{a="a";b="b";c=(a""b);print c}'
<font COLOR="#.7. &
& printf函数的使用:
字符转换: echo "65" |awk '{printf
"%c\n",$0}' & &输出A
&awk 'BEGIN {printf
"%f\n",999}' & &
& &输出999.000000
格式化输出:awk '{printf "%-15s %s\n",$1,$3}'
temp 将第一个域全部左对齐显示
<font COLOR="#.8. &
& 其他awk用法:
向一行awk命令传值:
awk '{if ($5
who | awk '{if ($1==user) print $1 " are
in " $2 ' user=$LOGNAME 使用环境变量
awk脚本命令:
开头使用 !/bin/awk -f
&,如果没有这句话自含脚本将不能执行,例子:
!/bin/awk -f
# all comment lines must start with a
# name: student_tot.awk
# to call: student_tot.awk
# prints total and average of club
student points
# print a header first
print "Student &
&Date & Member No.
&Grade &Age
&Points &Max"
print "Name &Joined
Gained &Point Available"
print"========================================================="
# let's add the scores of points
(tot+=$6);
# finished processing now let's print
the total and average point
print "Club student total points :" tot
print "Average Club Student points :" tot/N
<font COLOR="#.9. &
& awk数组:
awk的循环基本结构
For (element in array) print
array[element]
awk 'BEGIN
{record="123#456#789";split(record,myarray,"#")}&
END { for (i in myarray) {print
myarray[i]} }
<font COLOR="#.0
&awk中自定义语句
一.条件判断语句(if)
if(表达式) #if ( Variable in Array
格式中"语句1"可以是多个语句,如果你为了方便Unix
awk判断也方便你自已阅读,你最好将多个语句用{}括起来。Unix awk分枝结构允许嵌套,其格式为:
if(表达式)
else if(表达式)
[chengmo@localhost nginx]# awk
if(test&90)
print "very good";
if(test&60)
print "good";
print "no pass";
每条命令语句后面可以用“;”号结尾。
二.循环语句(while,for,do)
<font COLOR="#.while语句
while(表达式)
[chengmo@localhost nginx]# awk
while(i&=test)
<font COLOR="#50
<font COLOR="#.for 循环
for循环有两种格式:
for(变量 in 数组)
[chengmo@localhost nginx]# awk
for(k in ENVIRON)
print k"="ENVIRON[k];
AWKPATH=.:/usr/share/awk
OLDPWD=/home/web97
SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass
SELINUX_LEVEL_REQUESTED=
SELINUX_ROLE_REQUESTED=
LANG=zh_CN.GB2312
。。。。。。
说明:ENVIRON 是awk常量,是子典型数组。
for(变量;条件;表达式)
[chengmo@localhost nginx]# awk
for(i=0;i&=100;i++)
<font COLOR="#50
<font COLOR="#.do循环
{语句}while(条件)
[chengmo@localhost nginx]# awk
}while(i&=100)
<font COLOR="#50
以上为awk流程控制语句,从语法上面大家可以看到,与c语言是一样的。有了这些语句,其实很多shell程序都可以交给awk,而且性能是非常快的。
break 当 break 语句用于 while 或 for
语句时,导致退出程序循环。&
continue 当 continue 语句用于 while 或 for
语句时,使程序循环移动到下一个迭代。&
能能够导致读入下一个输入行,并返回到脚本的顶部。这可以避免对当前输入行执行其他的操作过程。&
语句使主输入循环退出并将控制转移到END,如果END存在的话。如果没有定义END规则,或在END中应用exit语句,则终止脚本的执行。&
A.awk对多输入文件的执行顺序是,先将代码作用于第一个文件(一行行读入),然后该重复的代码又作用于第二个文件,再作用于第三个文件。
B.awk对多输入文件的执行顺序产生了行序号的问题。当第一个文件执行完,下次读入第二个文件,那么第二个文件的第一行怎么算呢?如果又计为1的话,那不就两个1了么?(因为第一个文件也有第一行)。这就是NR和FNR的问题。
:全局行数(第二个文件的第一行接着第一个文件尾行数顺序计数)
&FNR:当前文件自身的行数(不考虑前几个输入文件的自身行数及总数)
&例如:data1.txt中有40行,data2.txt中有50行,那么awk ‘{}’
data1.txt data2.txt
&的值依次为:1,2……40,41,42……90
& &FNR的值依次为:1,2……40, 1,
getline函数说明:
getline语句用于简单地读取一条记录。如果用户有一个数据记录类似两个物理记录,那么getline将尤其有用。它完成一般字段的分离(设置字段变量$0
FNR NF NR)。如果成功则返回1,失败则返回0(到达文件尾)。
A.getline从整体上来说,应这么理解它的用法:
& 当其左右无重定向符 | 或 &
时,getline作用于当前文件,读入当前文件的第一行给其后跟的变量&
或$0(无变量);应该注意到,由于awk在处理getline之前已经读入了一行,所以getline得到
& 的返回结果是隔行的。
& 当其左右有重定向符 | 或 &
时,getline则作用于定向输入文件,由于该文件是刚打开,并没有被
awk读入一行,只是getline读入,那么getline返回的是该文件的第一行,而不是隔行。
B.getline用法大致可分为三大类(每大类又分两小类),即总共有6种用法。代码如下:
nawk ‘BEGIN{“cat data.txt”|
print d}’ data2.txt&
nawk ‘BEGIN{“cat data.txt”|
print $0}’ data2.txt
nawk ‘BEGIN{getline d &
“data.txt”; print d}’ data2.txt&
nawk ‘BEGIN{getline &
“data.txt”; print $0}’ data2.txt
以上四行代码均实现“只打印data.txt文件的第一行”(若打印全部行,用循环)
‘BEGIN{FS=”:”;while(getline&”/etc/passwd”&0){print
$1}}’ data.txt
nawk ‘{ print d”#”$3}’
&awk首先读入第一行,接着处理getline函数,然后把下一行指定给变量d,再先打印d,由于d后面有换行符,所以后面紧跟的#会覆盖d,后面的$3同样也会覆盖d。
nawk ‘{ print $0”#”$3}’
awk首先读入第一行接着处理getline函数,然后把下一行指定给$0,现在的$0已经是下一行内容,后面的#和$3(从$0中取)会覆盖$0的内容。
在awk中,有时需要调用系统工具来完成awk不擅长的工作,awk提供的system命令可以用来执行,但收不到外部工具的输出结果。好在可以运用getline来满足这个需求。例如
&datecommand="/bin/date -j -f
\"%d/%b/%Y:%H:%M:%S\" " $olddatestr " \"+%Y%m%d
%H%M%S\"";
&datecommand | getline
newdatestr&
&close(datecommand);
外部命令需要awk占用一个文件描述符,而awk最多能打开的文件有一个上限,而且不大(比如说16),所以最后做一个close是好习惯。把命令串定义为一个变量也是为了close的时候方便
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 awk 调用外部变量 的文章

 

随机推荐