LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 2403|回复: 20

请问在AWK中如何打印第N个字段以及其后的所有字段?

[复制链接]
发表于 2006-3-6 21:46:03 | 显示全部楼层 |阅读模式
我知道:

  1. print $10
复制代码

是打印第10个字段,但是要按原样把第10个字段以及其后的字段打印出来应该怎么做呢?
比如说处理ls -l 的输出的时候,如果文件名有空格的话,就有可能被awk分成单独的字段。
那么该如何处理呢?谢谢!
发表于 2006-3-6 21:53:29 | 显示全部楼层
awk '{ for (i=10;i<=NF;i++) print $i }'
回复 支持 反对

使用道具 举报

发表于 2006-3-7 05:14:23 | 显示全部楼层
Post by johnny_jiang
awk '{ for (i=10;i<=NF;i++) print $i }'

这可不是按原样了。所有的域都将单独打印一行。
回复 支持 反对

使用道具 举报

发表于 2006-3-7 09:03:49 | 显示全部楼层
Post by yongjian
这可不是按原样了。所有的域都将单独打印一行。


哦,对头,多谢yongjian兄提点,有点想当然了,

awk '{ for (i=10;i<=NF;i++) printf "%s ",$i } { print "" }'

Take a shot
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-7 09:13:45 | 显示全部楼层
Post by johnny_jiang
哦,对头,多谢yongjian兄提点,有点想当然了,

awk '{ for (i=10;i<=NF;i++) printf "%s ",$i } { print "" }'

Take a shot

这也不一定是按照原样了,万一文件名里面有Tab或者是其他空白字符(比如说两个空格呢?)
回复 支持 反对

使用道具 举报

发表于 2006-3-7 11:38:21 | 显示全部楼层
try this, at least it runs well on my computer



  1. # filename: format-ls

  2. BEGIN { N=6 }        # the column you wanna display from

  3. {

  4. rstring=""

  5. for (i=1;i<=N-1;i++) rstring=(rstring?rstring"[\t ]*":"")"[a-zA-Z0-9_-]*"

  6. match($0,rstring,a)

  7. print substr($0,RLENGTH+1)

  8. }

复制代码


  1. bash# ls -l | awk -f format-ls
复制代码
回复 支持 反对

使用道具 举报

 楼主| 发表于 2006-3-7 21:00:28 | 显示全部楼层
恩!谢谢!稍微修改一下就基本上可以工作在大部分情况下了!
回复 支持 反对

使用道具 举报

发表于 2006-3-8 10:00:42 | 显示全部楼层
johnny_jiang兄能否详细解释一下下面这句代码的含义:

  1. for (i=1;i<=N-1;i++) rstring=(rstring?rstring"[\t ]*":"")"[a-zA-Z0-9_-]*"
复制代码

我想看这句运行后rstring的内容,就把你的脚本改了一下

  1. # filename: format-ls
  2. BEGIN { N=6 }        # the column you wanna display from
  3. {
  4. rstring=""
  5. for (i=1;i<=N-1;i++) rstring=(rstring?rstring"[\t ]*":"")"[a-zA-Z0-9_-]*"
  6. print  rstring
  7. #match($0,rstring,a)
  8. #print substr($0,RLENGTH+1)
  9. }
复制代码

结果输出:

  1. [a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*
  2. [a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*
  3. [a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*
  4. [a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*
  5. [a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*
  6. [a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*[       ]*[a-zA-Z0-9_-]*
复制代码

但你的程序是正确的,我就是看不懂上面的那句。
回复 支持 反对

使用道具 举报

发表于 2006-3-8 10:56:11 | 显示全部楼层

  1. for (i=1;i<=N-1;i++) rstring=(rstring?rstring"[\t ]*":"")"[a-zA-Z0-9_-]*"
复制代码


其实是这样的,rstring是为了用来匹配那些不需要显示的column,举例来说:



  1. bash# ls -l

  2. -rwxr-xr-x  1 genesis users 1092 Mar  8 10:35 read-redirection
  3. -rwxr-xr-x  1 genesis users  285 Feb 24 14:30 seeding-random
  4. -rwxr-xr-x  1 genesis users  250 Mar  7 14:25 select
  5. -rwxr-xr-x  1 genesis users  164 Mar  6 13:00 setty
  6. -rwxr-xr-x  1 genesis users  623 Mar  7 15:43 spawn.sh
  7. -rwxr-xr-x  1 genesis users  181 Feb 23 16:27 t-out
  8. -rwxr-xr-x  1 genesis users  328 Feb 21 12:46 tifs
  9. -rwxr-xr-x  1 genesis users  599 Feb 21 16:14 timed-input
  10. -rwxr-xr-x  1 genesis users  370 Feb 23 15:30 timeout
  11. -rwxr-xr-x  1 genesis users  212 Feb 21 16:47 tmout
  12. -rwxr-xr-x  1 genesis users  582 Feb 21 13:33 trpexit

复制代码


如果我只想显示genesis以后的内容,那么
rstring=[a-zA-Z0-9_-]*[  ]*[a-zA-Z0-9_-]*
其实就是匹配
-rwxr-xr-x  1

[a-zA-Z0-9_-]* 匹配 -rwxr-xr-x
[\t ]* 匹配中间的whitespace
[a-zA-Z0-9_-]* 匹配 1

然后用match来赋值RLENGTH,在用substr取出需要的部分

我相信还有其他更好的方法,我这个比较呆板,个人觉得
回复 支持 反对

使用道具 举报

发表于 2006-3-8 12:49:28 | 显示全部楼层
这条命令里"?"和":"的作用又是什么呢?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表