Chinaunix
标题:
寻找文件中的多行多列内容并输出对应行(比较繁琐,谢谢)
[打印本页]
作者:
greaterwei
时间:
2017-09-12 19:05
标题:
寻找文件中的多行多列内容并输出对应行(比较繁琐,谢谢)
本帖最后由 greaterwei 于 2017-09-14 18:10 编辑
文件refs.dat 包含以下多行多列内容
ACBACU ACPRCU …
ACCAFA ADESXA …
CATPAL AOXSCH …
CDACET …
CDCAZA …
…
…
文件cons.dat中内容如下:
ACBACU 1.397 0.854 2.782 0 0 0.211 4 4 4 4 4 4 ...
ACPRCU 3.535 2.441 1.565 0 0 0.373 3 2 3 3 2 3 ...
AOXSCH 2.159 1.340 3.080 0 0 0.365 3 2 3 3 2 3 ...
CATPAL 3.807 2.039 2.788 0 0 0.386 4 3 3 4 3 3 ...
CDCAZA 4.439 2.496 1.525 0 0 0.390 3 1 3 3 1 3 ...
…
…
refs.dat 中有约50列数据,每列长度不一;cons.dat中有约20万行数据,每行10列。
现在要求检测
cons.dat 第一列
中是否含有refs.dat中的内容并输出
检测规则为:先在
cons.dat 第一列
中 检测
refs.dat 的第一列
内容,然后提取对应行内容,并输出成文件1.dat;
再在
cons.dat 第一列
中 检测
refs.dat的 第二列
内容,然后提取对应行内容,并输出成文件2.dat;
...
...
最后,
未找到
的refs.dat的内容按列生成新文件ref-left.dat refs.dat中
第n列
的结果若
全部找到
,则在ref-left.dat中依然生成
空列
;若
一个都没找到
,依然生成
空文件
n.dat
如此,输出ref-left.dat的内容应为:
ACCAFA ADESXA …
CDACET … …
… …
…
1.dat的内容应为:
ACBACU 1.397 0.854 2.782 0 0 0.211 4 4 4 4 4 4 ...
CATPAL 3.807 2.039 2.788 0 0 0.386 4 3 3 4 3 3 ...
CDCAZA 4.439 2.496 1.525 0 0 0.390 3 1 3 3 1 3 ...
…
…
2.dat的内容应为:
ACPRCU 3.535 2.441 1.565 0 0 0.373 3 2 3 3 2 3 ...
AOXSCH 2.159 1.340 3.080 0 0 0.365 3 2 3 3 2 3 ...
…
…
3.dat的内容应为:...
最后,如果能够把上述结果再分别直接输出至report.xls文件的
各个sheet
(即sheet1是ref-left.dat的内容,sheet2是1.dat的内容,sheet3是2.dat的内容,...)更好。
十分感谢!
作者:
Newbee_Mofi
时间:
2017-09-12 22:10
太高深了,飘过~
作者:
greaterwei
时间:
2017-09-12 22:43
回复
2#
Newbee_Mofi
我可以一个一个的弄,但是那样的话太浪费时间了
作者:
Newbee_Mofi
时间:
2017-09-12 22:55
回复
3#
greaterwei
感觉你使用shell的水平 比我高多了 我才刚学会定时任务 简单的提数脚本编写
作者:
greaterwei
时间:
2017-09-12 23:19
回复
4#
Newbee_Mofi
我只会皮毛。。就是来求助的。。
作者:
龙牙地主天
时间:
2017-09-13 10:28
awk 'NR==FNR{a[$1]=$0 ; next}{for(i in a) {if($1==i) {print a[$1] > "1.dat" ; $1="\t"} ; if($2==i) {print a[$2] > "2.dat" ; $2="\t"}} $0=$0 ; print > "ref-left.dat"}' cons.dat refs.dat
复制代码
作者:
zxy877298415
时间:
2017-09-13 10:44
回复
1#
greaterwei
awk 'FNR==NR{for(i=1;i<=NF;i++) a[NR" "i]=$i;m=NR;n=NF;next}{for(i=1;i<=m;i++) {for(j=1;j<=n;j++) if(a[i" "j]==$1) {print $0 >>j".dat";delete a[i" "j]}}}END{for(i=1;i<=m;i++) {for(j=1;j<=n;j++) {if(a[i" "j]) s=s?s" "a[i" "j]:a[i" "j]} b[++t]=s;s=""} for(i=1;i<=t;i++) if(b[i]) print b[i]>>"ref-left.dat"}' refs.dat cons.dat
复制代码
excel的那个自己手工来吧,不知道shell怎么操作excel!
作者:
本友会机友会摄友会
时间:
2017-09-13 13:48
提示:
作者被禁止或删除 内容自动屏蔽
作者:
wh7211
时间:
2017-09-13 21:13
回复
1#
greaterwei
awk 'FILENAME==ARGV[1]{a[$1]=$0;next}{for(i in a){for(j=1;j<=NF;j++){if($j~i){$j="";print a[i]>j".dat"}}}}{for(i=1;i<=NF;i++){s[i]=s[i]?s[i]" "$i:$i}}END{m1=split(s[1],t1);m2=split(s[2],t2);m=m1>m2?m1:m2;for(i=1;i<=m;i++){print t1[i],t2[i]>"ref-left.dat"}}' cons.dat refs.dat
复制代码
作者:
greaterwei
时间:
2017-09-13 22:14
回复
6#
龙牙地主天
谢谢您的回复!您的代码可以运行,但是3列过后的数据没有输出
作者:
greaterwei
时间:
2017-09-13 22:15
本帖最后由 greaterwei 于 2017-09-13 22:23 编辑
回复
9#
wh7211
十分感谢您的回复!
您的代码可以运行,但是ref-left.dat 数据好像只能输出两列,三列之后的没有输出
作者:
greaterwei
时间:
2017-09-13 22:22
回复
7#
zxy877298415
谢谢前辈! 您的代码可以运行,但是只能输出第一列的数据
作者:
greaterwei
时间:
2017-09-13 22:38
回复
8#
本友会机友会摄友会
谢谢前辈的回复。
1. 我的数据在20万行左右
2. 取交集,但是要输出的是对应处整行的内容:也就是在cons.dat 第一列中 遍历refs.dat第一列所有的内容, 找到对应后,输出cons.dat中此处整行的内容
作者:
jason680
时间:
2017-09-14 07:26
回复
1#
greaterwei
How about this way ...
$ awk 'function p(s){print "Output: "s}FNR==NR{for(n=1;n<=NF;++n)a[$n]=n;next}{if($1 in a){f=a[$1]".dat";print>f;if(a[$1]==c+1){p(f);++c}delete a[$1]}}END{for(n in a){f="ref-left.dat";print n>f;if(!d++)p(f)}}' refs.dat cons.dat
Output: 1.dat
Output: 2.dat
Output: ref-left.dat
作者:
wh7211
时间:
2017-09-14 09:35
回复
11#
greaterwei
refs.dat中一共有多少列?
作者:
mwl940602
时间:
2017-09-14 09:46
awk 'NR==FNR{for(i=1;i<=NF;i++) {a[NR""i]=$i } col=(col<NF)?NF:col row=NR next } {b[$1]=$0 } END{for(i=1;i<=row;i++) {for(j=1;j<=col;j++) {if(b[a[i""j]]!="") {print b[a[i""j]] > j".dat"; a[i""j]=""} printf("%-6s ",a[i""j]) > ref-left".dat"} printf("\n") } }' resf.dat cons.dat
作者:
mwl940602
时间:
2017-09-14 09:47
awk 'NR==FNR{for(i=1;i<=NF;i++) {a[NR""i]=$i } col=(col<NF)?NF:col row=NR next } {b[$1]=$0 } END{for(i=1;i<=row;i++) {for(j=1;j<=col;j++) {if(b[a[i""j]]!="") {print b[a[i""j]] > j".dat"; a[i""j]=""} printf("%-6s ",a[i""j]) > ref-left".dat"} printf("\n") } }' resf1.dat cons1.dat
作者:
mwl940602
时间:
2017-09-14 09:47
awk 'NR==FNR{for(i=1;i<=NF;i++) {a[NR""i]=$i } col=(col<NF)?NF:col row=NR next } {b[$1]=$0 } END{for(i=1;i<=row;i++) {for(j=1;j<=col;j++) {if(b[a[i""j]]!="") {print b[a[i""j]] > j".dat"; a[i""j]=""} printf("%-6s ",a[i""j]) > ref-left".dat"} printf("\n") } }' resf.dat cons.dat
作者:
mwl940602
时间:
2017-09-14 09:48
awk 'NR==FNR{for(i=1;i<=NF;i++) {a[NR""i]=$i } col=(col<NF)?NF:col row=NR next } {b[$1]=$0 } END{for(i=1;i<=row;i++) {for(j=1;j<=col;j++) {if(b[a[i""j]]!="") {print b[a[i""j]] > j".dat"; a[i""j]=""} printf("%-6s ",a[i""j]) > ref-left".dat"} printf("\n") } }' resf1.dat cons1.dat
作者:
mwl940602
时间:
2017-09-14 09:48
awk 'NR==FNR{for(i=1;i<=NF;i++) {a[NR""i]=$i } col=(col<NF)?NF:col row=NR next } {b[$1]=$0 } END{for(i=1;i<=row;i++) {for(j=1;j<=col;j++) {if(b[a[i""j]]!="") {print b[a[i""j]] > j".dat"; a[i""j]=""} printf("%-6s ",a[i""j]) > ref-left".dat"} printf("\n") } }' resf.dat cons.dat
作者:
本友会机友会摄友会
时间:
2017-09-14 11:34
提示:
作者被禁止或删除 内容自动屏蔽
作者:
jason680
时间:
2017-09-14 12:47
本友会机友会摄友会 发表于 2017-09-14 11:34
hi ,各位,我认为这是excel中点鼠标问题。
1 把两个txt导入excel。表1,表2。
2 交集即取重。生成表3。按 ...
...那是【偏执狂撸班】
Yes, You did it.
作者:
本友会机友会摄友会
时间:
2017-09-14 12:59
提示:
作者被禁止或删除 内容自动屏蔽
作者:
mwl940602
时间:
2017-09-14 13:24
本友会机友会摄友会 发表于 2017-09-14 11:34
hi ,各位,我认为这是excel中点鼠标问题。
1 把两个txt导入excel。表1,表2。
2 交集即取重。生成表3。按 ...
鲁班好像还创造了锯子吧,人家也没有非用斧子解决问题。对好多初学者来说,遇到问题考虑的不是哪个工具好用,而是我会用哪个?您老用 PS无可厚非,喜欢也好,牛B也罢,去争论编程语言的好坏是没有意义的,实用才重要
作者:
greaterwei
时间:
2017-09-14 17:57
回复
15#
wh7211
两组数据。一组46列,另一组50列。谢谢前辈!
作者:
greaterwei
时间:
2017-09-14 18:18
回复
14#
jason680
谢谢前辈大神!但是您的代码运行的结果有点问题:首先输出的n.dat结果匹配的行数不对;其次 ref-left的结果只有一列。谢谢!
作者:
greaterwei
时间:
2017-09-14 18:23
回复
21#
本友会机友会摄友会
首先非常感谢您!然后很遗憾,你给交集只能匹配输出单列,
然后我有用excel的MATCH和ADDRESS功能,是能完美解决问题;
但是20万行,50多列的数据,excel根本运行不了,总是卡死自动退出。。。
作者:
greaterwei
时间:
2017-09-14 18:23
本帖最后由 greaterwei 于 2017-09-14 18:24 编辑
回复
21#
本友会机友会摄友会
作者:
greaterwei
时间:
2017-09-14 18:28
回复
20#
mwl940602
十分感谢,但是您的代码有 syntax error,您能再看下么? 谢谢
作者:
本友会机友会摄友会
时间:
2017-09-14 18:40
提示:
作者被禁止或删除 内容自动屏蔽
作者:
本友会机友会摄友会
时间:
2017-09-14 18:46
提示:
作者被禁止或删除 内容自动屏蔽
作者:
wh7211
时间:
2017-09-14 21:16
回复
25#
greaterwei
文件refs.dat内容如下:
ACBACU ACPRCU aaa
ACCAFA ADESXA bbb
CATPAL AOXSCH ccc
CDACET 111 ddd
CDCAZA
文件cons.dat内容如下:
ACBACU 1.397 0.854 2.782 0 0 0.211 4 4 4 4 4 4
ACPRCU 3.535 2.441 1.565 0 0 0.373 3 2 3 3 2 3
AOXSCH 2.159 1.340 3.080 0 0 0.365 3 2 3 3 2 3
CATPAL 3.807 2.039 2.788 0 0 0.386 4 3 3 4 3 3
CDCAZA 4.439 2.496 1.525 0 0 0.390 3 1 3 3 1 3
以下代码适合任意列,重新生成的文件ref-left.dat每列的行数是不同的,因此为了保证数据的准确性防止串列,增加了“---”符号。
awk 'FILENAME==ARGV[1]{a[$1]=$0;next}{m=m>NF?m:NF;for(i in a){for(j=1;j<=NF;j++){if($j~i){$j="";print a[i]>j".dat"}}}}{for(i=1;i<=NF;i++){s[i]=s[i]?s[i]" "$i:$i}}END{for(i=1;i<=m;i++){split(s[i],t);n=n>length(t)?n:length(t)};for(i=1;i<=m;i++){split(s[i],t);for(j=1;j<=n;j++){t[j]=t[j]?t[j]:"---";p[j]=p[j]?p[j]" "t[j]:t[j]}}for(i=1;i<=n;i++){print p[i]>"ref-left.dat"}}' cons.dat refs.dat
复制代码
输出:
$ cat 1.dat
ACBACU 1.397 0.854 2.782 0 0 0.211 4 4 4 4 4 4
CATPAL 3.807 2.039 2.788 0 0 0.386 4 3 3 4 3 3
CDCAZA 4.439 2.496 1.525 0 0 0.390 3 1 3 3 1 3
$ cat 2.dat
ACPRCU 3.535 2.441 1.565 0 0 0.373 3 2 3 3 2 3
AOXSCH 2.159 1.340 3.080 0 0 0.365 3 2 3 3 2 3
$cat ref-left.dat
ACCAFA ADESXA aaa
CDACET 111 bbb
--- --- ccc
--- --- ddd
作者:
greaterwei
时间:
2017-09-14 21:55
本帖最后由 greaterwei 于 2017-09-14 22:04 编辑
回复
31#
本友会机友会摄友会
好的,十分感谢大神! 我再琢磨琢磨
作者:
greaterwei
时间:
2017-09-14 22:02
回复
32#
wh7211
十分感谢!您的代码在数据量少的时候非常好使!!!
但是数据一多后就不能输出文件了,而且ref-left就会出现错误,不知道什么原因。
数据输入的时候我需要注意什么么? 谢谢!
作者:
mwl940602
时间:
2017-09-15 00:58
awk 'NR==FNR{for(i=1;i<=NF;i++){a[NR""i]=$i } col=(col<NF)?NF:col; row=NR; next}{b[$1]=$0 }END{for(i=1;i<=row;i++){for( j=1;j<=col;j++){if(b[a[i""j]]!=""){print b[a[i""j]] > j".dat"; a[i""j]="" } printf("%-6s ",a[i""j]) > "ref-left.dat"}printf("\n") > "ref-left.dat"} }' refs.dat cons.dat
作者:
wh7211
时间:
2017-09-15 13:50
本帖最后由 wh7211 于 2017-09-15 14:53 编辑
回复
34#
greaterwei
从给定的信息来看:
文件cons.dat:20万行
文件refs.dat:行数不确定,46列或50列
awk处理20万行数据不会有任何压力,请检查一下源文件是否是格式化文档。另外可以把文件ref-left出现错误的截图贴上来分析一下。
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2