请教多行文本关联处理的方法.

sh/bash/dash/ksh/zsh等Shell脚本
回复
guangjian
帖子: 7
注册时间: 2010-07-17 14:01
送出感谢: 0
接收感谢: 0

请教多行文本关联处理的方法.

#1

帖子 guangjian » 2011-04-20 16:15

请教多行文本关联处理的方法.

一个文件有多行, 编排的情况可能如下.
行号. 内容:
1. 姓名:
2. 年龄:
3. ...
4. ...
5. 姓名:
6: 年龄:
7...

目的:
读取每一行, 当发现包含姓名, 则把姓名取出来, 放到变量A, 再找下一行, 必须为该姓名对应的年龄, 放到变量B, 把A和B组成一行, 添加到一个输出文件中.
继续读取下面一行, 直到文件结束.

基本考虑用shell, sed 来处理, 但感觉处理比较复杂, 哪位能提供比较好的建议.
头像
lilydjwg
论坛版主
帖子: 4163
注册时间: 2009-04-11 23:46
系统: Arch Linux
送出感谢: 11 次
接收感谢: 127 次
联系:

Re: 请教多行文本关联处理的方法.

#2

帖子 lilydjwg » 2011-04-20 16:24

类似的问题已经在某个帖子里讨论过了。。。
guangjian
帖子: 7
注册时间: 2010-07-17 14:01
送出感谢: 0
接收感谢: 0

Re: 请教多行文本关联处理的方法.

#3

帖子 guangjian » 2011-04-20 16:48

能告知是哪个吗? 我没找到
头像
lilydjwg
论坛版主
帖子: 4163
注册时间: 2009-04-11 23:46
系统: Arch Linux
送出感谢: 11 次
接收感谢: 127 次
联系:

Re: 请教多行文本关联处理的方法.

#4

帖子 lilydjwg » 2011-04-20 18:42

guangjian 写了:能告知是哪个吗? 我没找到
找得累死我了~~

viewtopic.php?f=163&t=228131
sk1418
帖子: 229
注册时间: 2007-07-01 17:36
系统: (En):System
来自: (En):address
送出感谢: 2 次
接收感谢: 3 次
联系:

Re: 请教多行文本关联处理的方法.

#5

帖子 sk1418 » 2011-04-20 20:21

guangjian 写了:请教多行文本关联处理的方法.

一个文件有多行, 编排的情况可能如下.
行号. 内容:
1. 姓名:
2. 年龄:
3. ...
4. ...
5. 姓名:
6: 年龄:
7...

目的:
读取每一行, 当发现包含姓名, 则把姓名取出来, 放到变量A, 再找下一行, 必须为该姓名对应的年龄, 放到变量B, 把A和B组成一行, 添加到一个输出文件中.
继续读取下面一行, 直到文件结束.

基本考虑用shell, sed 来处理, 但感觉处理比较复杂, 哪位能提供比较好的建议.
你没交代清楚,你这个文件除了姓名,年龄是否还有别的内容?比如:

代码: 全选

 姓名: a
 年龄:23
 姓名: ab
 年龄:13
 姓名: ac
 年龄:30
还是:

代码: 全选

 姓名: a
 年龄:23
 子女:0
 配偶: 8
 姓名: ab
 年龄:13
 子女:10
 配偶: 0
 姓名: ac
 年龄:30
 子女:2
 配偶: 1
就说第一种,因为简单,呵呵。 :em02
其实不用你说的弄那么多变量,你不就是要把相应的姓名年龄放一行么,这样行么?

代码: 全选

kent$ awk  '{printf NR%2? $0 ", ":$0 "\n"}' t.txt
姓名: a, 年龄:23
姓名: ab, 年龄:13
姓名: ac, 年龄:30
---
regards,

Kent
fnan
帖子: 919
注册时间: 2009-07-01 22:04
送出感谢: 0
接收感谢: 13 次

Re: 请教多行文本关联处理的方法.

#6

帖子 fnan » 2011-04-20 21:04

我一般喜欢适应不同文本格式通用写法:
kose5@kose5-Aspire-4552:~$ cat t.txt
*
姓名: a
年龄:23
子女:0
配偶: 8
有小三
*
姓名: ab
年龄:13
子女:10
配偶: 0
姓名: ac
年龄:30
子女:2
配偶: 1
kose5@kose5-Aspire-4552:~$ awk '{if (match($0,"姓名")) a=$0; if (match($0,"年龄")) print a " " $0}' t.txt
姓名: a 年龄:23
姓名: ab 年龄:13
姓名: ac 年龄:30
kose5@kose5-Aspire-4552:~$
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
sk1418
帖子: 229
注册时间: 2007-07-01 17:36
系统: (En):System
来自: (En):address
送出感谢: 2 次
接收感谢: 3 次
联系:

Re: 请教多行文本关联处理的方法.

#7

帖子 sk1418 » 2011-04-20 21:46

在你基础上来个排错的:

代码: 全选

*
姓名: a
年龄:23
年龄:23xxxxxxx000000
姓名: axxxxxxxxxxxxxx
姓名: bxxxxxxxxxxxxxx
子女:0
配偶: 8
有小三
*
姓名: ab
年龄:13
子女:10
配偶: 0
姓名: ac
年龄:30
子女:2
配偶: 1

代码: 全选

awk  '{a=($0~"姓名")?$0:a; if($0~"年龄"){ a=a", "$0; if(a~"姓名" && a~"年龄")print a;a=""}}' t.txt
姓名: a, 年龄:23
姓名: ab, 年龄:13
姓名: ac, 年龄:30
---
regards,

Kent
guangjian
帖子: 7
注册时间: 2010-07-17 14:01
送出感谢: 0
接收感谢: 0

Re: 请教多行文本关联处理的方法.

#8

帖子 guangjian » 2011-04-20 22:05

多谢各位, 受益匪浅那. awk功能的确很强大.
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

Re: 请教多行文本关联处理的方法.

#9

帖子 eexpress » 2011-04-20 22:07

awk直接可以分段。
当然,不如perl强。lol
● 鸣学
fnan
帖子: 919
注册时间: 2009-07-01 22:04
送出感谢: 0
接收感谢: 13 次

Re: 请教多行文本关联处理的方法.

#10

帖子 fnan » 2011-04-20 22:16

另一种方式:
kose5@kose5-Aspire-4552:~$ cat t.txt
*
姓名: a
年龄:23
年龄:23xxxxxxx000000
姓名: axxxxxxxxxxxxxx
姓名: bxxxxxxxxxxxxxx
子女:0
配偶: 8
有小三
*
姓名: ab
年龄:13
子女:10
配偶: 0
姓名: ac
年龄:30
子女:2
配偶: 1
kose5@kose5-Aspire-4552:~$ awk '{if (match($0,"姓名")) {a=$0;b=NR} if (match($0,"年龄")) {if (NR == (b+1)) print a " " $0}}' t.txt
姓名: a 年龄:23
姓名: ab 年龄:13
姓名: ac 年龄:30
kose5@kose5-Aspire-4552:~$
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
头像
eexpress
帖子: 58428
注册时间: 2005-08-14 21:55
来自: 长沙
送出感谢: 4 次
接收感谢: 256 次

Re: 请教多行文本关联处理的方法.

#11

帖子 eexpress » 2011-04-20 22:22

awk -F 姓名

直接分段。
● 鸣学
guangjian
帖子: 7
注册时间: 2010-07-17 14:01
送出感谢: 0
接收感谢: 0

Re: 请教多行文本关联处理的方法.

#12

帖子 guangjian » 2011-04-20 23:17

希望产生下面的输出, 前面的实现好像还差一点.
Input:
cat test.txt
tesateta
asdfasdf
asdfasdf:asfasd
asdfasdf:asdfads
姓名:aaa
年龄:bbb
成绩:88
tset
asdfasdf
ass
姓名:ccc
年龄:ddd
成绩:98
asdfasdf
sk1418
帖子: 229
注册时间: 2007-07-01 17:36
系统: (En):System
来自: (En):address
送出感谢: 2 次
接收感谢: 3 次
联系:

Re: 请教多行文本关联处理的方法.

#13

帖子 sk1418 » 2011-04-21 17:15

guangjian 写了:希望产生下面的输出, 前面的实现好像还差一点.
Input:
cat test.txt
tesateta
asdfasdf
asdfasdf:asfasd
asdfasdf:asdfads
姓名:aaa
年龄:bbb
成绩:88
tset
asdfasdf
ass
姓名:ccc
年龄:ddd
成绩:98
asdfasdf
你到底说的是输入还是输出阿? 一帮人折腾了半天,发现还没明白你想要的是什么。。。。 :em20
---
regards,

Kent
头像
trigger
帖子: 1588
注册时间: 2006-10-25 18:08
送出感谢: 1 次
接收感谢: 0

Re: 请教多行文本关联处理的方法.

#14

帖子 trigger » 2011-04-22 10:01

动不动就循环,就数组,看的老衲蛋疼
cat test.txt
tesateta
asdfasdf
asdfasdf:asfasd
asdfasdf:asdfads
姓名:aaa
年龄:bbb
成绩:88
tset
asdfasdf
ass
姓名:ccc
年龄:ddd
成绩:98
asdfasdf

grep -E '姓名|年龄' test.txt | sed 'N;s/\n/\t/'
姓名:aaa 年龄:bbb
姓名:ccc 年龄:ddd
楼主真是一派胡言,真可谓:“两个黄鹂鸣翠柳,不知所云;一行白鹭上青天,不知所止“。本来不想和你辩论,今天气愤不过,和你理论一番。我国宪法写得清清楚楚:“一夜夫妻百日恩,七楼以上才有电梯”。这个想必你知道,既然知道,你就不能断章取义,就算是天气预报,它还有不准的时候呢!!!再者说了,那中国银行也不是你一家开的。人家马拉多纳都结婚了,你还拿着粮票顶什么用呢。真是滑天下之大稽。前些日子,全国人大刚刚开过会,郑重声明:“中国不搞多party制,存栏母猪给补贴”。多好的事呢,楞让你这号人给搅混了。
fnan
帖子: 919
注册时间: 2009-07-01 22:04
送出感谢: 0
接收感谢: 13 次

Re: 请教多行文本关联处理的方法.

#15

帖子 fnan » 2011-04-23 0:03

有排错的比较好:
kose5@kose5-Aspire-4552:~$ grep -E '姓名|年龄' t.txt|tr "\n" " "|grep -o '姓名[^姓年]*年龄[^姓年]*'
姓名: a 年龄:23
姓名: ab 年龄:13
姓名: ac 年龄:30
kose5@kose5-Aspire-4552:~$
不管想输出什么,加上就是,不管什么指令,骨子里算法一样。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
回复

回到 “Shell脚本”