欢迎 510814171 加入本站!
 免费注册  用户登陆  汇款方式  汇款确认  产品报价  联系我们  帮助中心
加入收藏
设为首页
会员体系
申请VIP
网站首页 光盘超市 软件下载 技术文章 专题 用户中心 VIP会员 技术论坛 网站留言 娱乐中心 卓越资源
今天是:2008年11月20日 星期四  您现在位于: 首页 → 技术文章 → 使用Linux 文本工...
   使用Linux 文本工具简化数据的提取(3)
作者:  出处:www.uplinux.net  更新时间: 2006年10月23日 

join

joinpaste 的一个很好的增强版本。join 只有在所要连接的文件共享某个共同的域时才会工作。

举例来说,考虑我们上面介绍 paste 时所使用的两个文件。下面是在使用 join 对其进行合并时所发生的事情:


# join fileone filetwo
      

注意这并没有显示任何东西。join 工具必须要在所操作的文件之间找到共同的域,默认情况下,它期望这个共同的域就是第一个域。

要了解这是如何工作的,我们可以尝试添加一些新内容。假设 fileone 现在包含以下内容:

aaaa    Jurassic Park
bbbb    AI
cccc    The Ring
dddd    The Mummy
eeee    Titanic
      

filetwo 现在包含以下内容:

aaaa    Neil    1111
bbbb    Steven  2222
cccc    Naomi   3333
dddd    Brendan 4444
eeee    Kate    5555
      

现在,再次尝试下面的命令:

# join fileone filetwo
aaaa    Jurassic Park    Neil    1111
bbbb    AI               Steven  2222
cccc    The Ring         Naomi   3333
dddd    The Mummy        Brendan 4444
eeee    Titanic          Kate    5555
      

此时第一个域相同的地方就会被识别出来,匹配项也就进行了合并。paste 是盲目地从每个文件中提取内容并创建输出结果;而 join 则是只合并那些匹配的行,这种匹配必须非常精确。举例来说,假设您向 filetwo 文件中添加一行内容:

aaaa    Neil    1111
bbbb    Steven  2222
ffff    Elisha  6666
cccc    Naomi   3333
dddd    Brendan 4444
eeee    Kate    5555
      

现在这个命令只会产生下面的输出结果了:

# join fileone filetwo
aaaa    Jurassic Park   Neil     1111
bbbb    AI              Steven   2222
      

只要这两个文件不再匹配了,就不会再执行任何操作了。第一个文件的每一行都匹配且只匹配于第二个文件相同行的默认域。如果找到匹配项,它们就会组成输出;否则就不再执行任何操作了。

默认情况下,join 只会查找第一个域进行匹配,并输出所有列的内容;不过我们可以对这种行为进行修改。-1 选项让我们可以指定使用哪个域作为 fileone 中的匹配项, -2 选项让我们可以指定使用哪个域作为 filetwo 中的匹配项。

举例来说,要对 fileone 的第二个域和 filetwo 的第三个域进行匹配,我们可以使用下面的语法:

# join -1 2 -2 3 fileone filetwo
      

-o 选项可以以 {file.field} 格式来指定输出结果。因此,要在匹配行上打印 fileone 的第二个域和 filetwo 的第三个域,语法为:

# join -o 1.2 -o 2.3 fileone filetwo
      

 

join:一个实际的例子

在实践中可以使用 join 工具最明显的方法是从 /etc/passwd 中提取用户名和对应的主目录项,并从 /etc/group 文件中提取组名。组名在 /etc/passwd 文件中是以数字的格式出现在第四个域中的。类似地,它们在 /etc/group 文件中是在第三个域中出现的。

# join -1 4 -2 3 -o 1.1 -o 2.1 -o 1.6 -t":" /etc/passwd /etc/group
root:root:/root
bin:bin:/bin
daemon:daemon:/sbin
adm:adm:/var/adm
lp:lp:/var/spool/lpd
nobody:nobody:/
vcsa:vcsa:/dev
rpm:rpm:/var/lib/rpm
nscd:nscd:/
ident:ident:/home/ident
netdump:netdump:/var/crash
sshd:sshd:/var/empty/sshd
rpc:rpc:/
      

 

awk

awk 是 Linux 上功能最为强大的工具之一。它本身实际上是一种编程语言,可以实现复杂的逻辑语句,还可以简化部分文本的提取。在本文那中我们将不会详细对其进行介绍,而是快速了解一下它的语法,并尝试几个实际的例子。

awk 命令包括一个模式和由一条或多条语句构成的操作,语法如下所示:


awk '/pattern/ {action}' file
      

请注意:

  • awk 测试指定文件中的每个记录是否符合模式匹配。如果找到匹配项,就执行指定的操作。
  • awk 可以在管道中作为过滤器,如果没有指定文件,它也可以从键盘(标准输入)中接收输入。

一种非常有用的操作是打印数据!下面是如何引用一条记录中的域。

  • $0 —— 整条记录
  • $1 —— 该记录中的第一个域
  • $2 —— 该记录中的第二个域

我们还可以从一条记录中提取多个域,之间使用逗号分开。

举例来说,要提取 /etc/passwd 文件中的第 6 个域,命令如下:

# awk -F: '{print $6}' /etc/passwd
/root
/bin
/sbin
/var/adm
/var/spool/lpd
/sbin
/sbin
/sbin
/var/spool/mail
/etc/news
/var/spool/uucp
      

注意 -F 是由预先定义的 FS 变量所定义的输入域分隔符。在我们这个例子中是空格。

要从 /etc/passwd 文件中提取第一个和第六个域,命令如下:

# awk -F: '{print $1,$6}' /etc/passwd
root /root
bin /bin
daemon /sbin
adm /var/adm
lp /var/spool/lpd
sync /sbin
shutdown /sbin
halt /sbin
mail /var/spool/mail
news /etc/news
uucp /var/spool/uucp
operator /root
      

要在域之间使用短横线代替冒号来打印这个文件的内容,命令如下:

# awk -F: '{OFS="-"}{print $1,$6}' /etc/passwd
root-/root
bin-/bin
daemon-/sbin
adm-/var/adm
lp-/var/spool/lpd
sync-/sbin
shutdown-/sbin
halt-/sbin
mail-/var/spool/mail
news-/etc/news
uucp-/var/spool/uucp
operator-/root
      

要使用短横线作为域之间的分隔符来打印文件,并且只以逆序打印第一个域和第六个域,命令如下:

# awk -F: '{OFS="-"}{print $6,$1}' /etc/passwd
/root-root
/bin-bin
/sbin-daemon
/var/adm-adm
/var/spool/lpd-lp
/sbin-sync
/sbin-shutdown
/sbin-halt
/var/spool/mail-mail
/etc/news-news
/var/spool/uucp-uucp
/root-operator
      

 

head

head 工具打印每个文件的最开始部分的内容(默认是 10 行)。如果没有给定文件,它就从标准输入中读入内容,如果给定了文件名就从文件中读入内容。

举例来说,如果我们希望从 memo 文件中提取前两行内容,命令如下:


# head -2 memo
In order to better serve the needs of our mass
market customers, ABC Publishing is
integrating the groups selling to this channel
for ABC General Reference and ABC Computer
Publishing. This change will allow us to
better coordinate our selling and marketing
efforts, as well as simplify ABC's
relationships with these customers in the
areas of customer service, co-op management,
and credit and collection. Two national
account managers, Ricky Ponting and Greeme
Smith, have joined the sales team as a result
of these changes.
      

我们可以使用 -c 选项指定要显示的字节个数。举例来说,如果我们希望从 memo 文件中读取前两个字节的内容,可以使用下面的命令:

# head -c 2 memo
In
      

 

tail

tail 工具打印每个文件的最末尾部分的内容(默认是 10 行)。如果没有给定文件,它就从标准输入中读入内容,如果给定了文件名就从文件中读入内容。

举例来说,如果我们希望从 memo 文件中提取最后两行内容,命令如下:

# tail -2 memo
Please join me in welcoming each of our new team members.
      

我们可以使用 -c 选项指定要显示的字节个数。举例来说,如果我们希望从 memo 文件中读取最后五个字节的内容,可以使用下面的命令:

# tail -c 5 memo
ers.
      

结束语

现在我们已经知道如何使用各种工具从标准 Linux 文件中向外提取数据了。一旦提取出数据之后,这些数据就可以进行查看、打印或重定向到其他文件或数据库中了。了解了如何使用这些有用的工具可以帮助我们减少花费在烦杂任务上的时间,从而能够成为一名效率更高的管理员。

 (本文已被浏览 4609 次)
 发布人:sdccf
 → 推荐给我的好友
上篇文章:使用Linux 文本工具简化数据的提取(2)
下篇文章:从Export理解Shell环境和变量生存期
 相关文章:
一个awk应用的小例子 几个Awk应用实例
awk分段处理记录并格式化输出(处理LDAP文件和DHCP记录) 用AWK实现DB2数据库Schema的同步
用grep搜索文本文件 awk自动创建格式化文本
如何成为一个UNIX系统的“好色”之徒 awk里面的一些隐藏特性
gawk 收取邮件测试 Linux下Grep命令使用的详细介绍
C与脚本语言awk混合编程 c语言调用gawk
linux被入侵后查找方法 shell学习资料汇总
Awk编程学习资料 Awk 实例(三)
Awk 实例(二) Awk 实例(一)
Unix awk使用手册(6) Unix awk使用手册(5)

相关搜索
查看百度中关于使用Linux 文本工具简化数据的提取(3)的更多内容
查看google中关于使用Linux 文本工具简化数据的提取(3)的更多内容
   文章分类
操作系统 |
SCO_UNIX  Sun_Solaris  IBM_AIX  HP_UX  Linux  BSD  Tru64_UNIX 
通用UNIX知识  Windows  Minix 
程序设计 |
Shell编程  C/C++  汇编  PHP  JAVA  Perl  Python 
ASP/HTML  XML  中间件 
数据库 |
Oracle  Informix  Sybase  Fox  DB2  SQL  MySQL 
PostgreSQL 
网络应用 |
网络应用 
计算机硬件 |
计算机主机  打印机  路由器  交换机  终端  磁带机  MO 
刻录机  终端服务器  调制解调器 
   文章评论
  → 评论内容 (点击查看)   共0条评论,每页显示5条评论   浏览所有评论
(没有相关评论)
  → 发表我的评论
您的姓名: 您的Email:
评论内容:
250字内
发表评论:      发表评论须知 →
  • 尊重网上道德,遵守《全国人大常委会关于维护互联网安全的决定》及中华人民共和国其他各项有关法律法;
  • 本站有权保留或删除您发表的任何评论内容;
  • 关于我们 ┋  网站留言 ┋  网站地图 ┋  友情链接 ┋  与我在线 ┋  汇款确认 ┋  管理 ┋  TOP
    Linux.Unix爱好者家园  http://www.unix-cd.com/
    联系我们:sdccf@163.com
    腾讯QQ: 7644599
    备案序号:鲁ICP备05000455号
    Copyright (c) 2001-2008 Unix-cd.com. All Rights Reserved.