Chinaunix
标题:
笔试一道AWK文本处理题
[打印本页]
作者:
stupid_lee
时间:
2014-09-02 11:47
标题:
笔试一道AWK文本处理题
123456 23 1000
234567 34 1234
345678 21 1234
456789 45 4532
234567 34 1233
234567 34 1234
345678 21 3445
其中第一列为ID号 第二列为级别 第三列为时间
题目要求,写一个AWK脚本处理文本,处理结果为
第一列显示ID
第二列过滤级别<30或者级别>40
第三列显示内容为,若为相同的ID号,计算时间之和
作者:
yestreenstars
时间:
2014-09-02 11:50
这题似曾相识,是TX的?
作者:
Herowinter
时间:
2014-09-02 12:02
回复
1#
stupid_lee
awk '$2<30||$2>40{a[$1" "$2]+=$3} END{for(i in a)print i,a[i]}' i
345678 21 4679
123456 23 1000
456789 45 4532
复制代码
作者:
stupid_lee
时间:
2014-09-02 12:25
回复
2#
yestreenstars
嘿嘿
作者:
prcardin
时间:
2014-09-02 12:33
企鹅的
作者:
Shell_HAT
时间:
2014-09-02 12:33
腾讯每年都考这个题目?
作者:
stupid_lee
时间:
2014-09-02 12:34
回复
6#
Shell_HAT
为什么你们都知道?我百度过结果没找到TX笔试题
作者:
stupid_lee
时间:
2014-09-02 12:40
Herowinter 发表于 2014-09-02 12:02
回复 1# stupid_lee
膜拜
作者:
wayflying
时间:
2014-09-02 12:46
腾讯面试给人的感觉是很学院气,喜欢问非常细节的问题,包括这类型笔试,如果不是天天写脚本,想一次性写好还是很难的。
作者:
super皮波
时间:
2014-09-02 12:46
第一次回答这样的问题,有错误请指教
awk '{if($2>=30 && $2<=40) {a[$1]+=$3;b[$1]=$2;next}} END{for (i in a) print i " " b[i] " " a[i]}' mytest.txt
作者:
super皮波
时间:
2014-09-02 12:50
貌似我写反了 你想留下的是<30和>40的
作者:
关阴月飞
时间:
2014-09-02 12:50
回复
10#
super皮波
请参考3楼
作者:
stupid_lee
时间:
2014-09-02 12:52
回复
9#
wayflying
我留空白了
作者:
super皮波
时间:
2014-09-02 12:53
回复
12#
关阴月飞
恩 3楼写的确实简单,刚开始学shell,方法比较笨,思路不开阔,跟着各位前辈学习学习
作者:
stupid_lee
时间:
2014-09-02 12:53
回复
10#
super皮波
又多了一种参考,感谢
作者:
super皮波
时间:
2014-09-02 12:54
回复
13#
stupid_lee
下次面试见
作者:
super皮波
时间:
2014-09-02 12:54
回复
15#
stupid_lee
我这是笨方法,3楼是高大上的写法,你学习他的,忽略我的就可以了,我是重在参与
作者:
stupid_lee
时间:
2014-09-02 12:56
回复
17#
super皮波
能学到你的也不错了,三楼的确让人羡慕嫉妒
作者:
Shell_HAT
时间:
2014-09-02 12:57
本帖最后由 Shell_HAT 于 2014-09-02 12:57 编辑
回复
11#
super皮波
我这里测试的时候,有没有等号都不对。
[root]# awk '{if($2>=30 && $2<=40) {a[$1]+=$3;b[$1]=$2;next}} END{for (i in a) print i " " b[i] " " a[i]}' a.txt
234567 34 3701
[root]# awk '{if($2>30 && $2<40) {a[$1]+=$3;b[$1]=$2;next}} END{for (i in a) print i " " b[i] " " a[i]}' a.txt
234567 34 3701
复制代码
作者:
super皮波
时间:
2014-09-02 13:02
回复
19#
Shell_HAT
你指的是哪里的等号 我这里测试的时候没发现问题呢
样本如下
123456 23 1000
234567 34 1234
345678 21 1234
456789 45 4532
234567 34 1233
234567 34 1234
345678 21 3445
888888 35 1000
999999 30 1000
awk '{if($2>=30 && $2<=40) {a[$1]+=$3;b[$1]=$2;next}} END{for (i in a) print i" " b
" " a
}' mytest.txt
234567 34 3701
999999 30 1000
888888 35 1000
作者:
Shell_HAT
时间:
2014-09-02 13:10
回复
20#
super皮波
你能否使用顶楼的数据,把3楼代码和你的代码的执行结果分别发出来看看。
作者:
super皮波
时间:
2014-09-02 13:12
回复
21#
Shell_HAT
我的正好写反了,我以为楼主想留下的是30到40之间的。楼主的本意是要过滤掉30到40之间的
作者:
Shell_HAT
时间:
2014-09-02 13:15
回复
22#
super皮波
知道了。
你的代码里面next命令是必须的吗?
作者:
super皮波
时间:
2014-09-02 13:19
回复
23#
Shell_HAT
next不是必须的,没啥作用,对awk用的不熟
作者:
Shell_HAT
时间:
2014-09-02 13:23
本帖最后由 Shell_HAT 于 2014-09-02 13:23 编辑
回复
24#
super皮波
还有就是 print 的时候直接用逗号就行了
print i,b[i],a[i]
复制代码
作者:
super皮波
时间:
2014-09-02 13:24
回复
25#
Shell_HAT
多谢指教。
作者:
wayflying
时间:
2014-09-02 13:44
仔细看了下3楼的,确实厉害,将域输出和数组下标非常巧妙地整合了。如果只用a[$1]+=$3也可以完成计算,但输出的结果缺少第二个域。
作者:
stupid_lee
时间:
2014-09-02 13:52
回复
27#
wayflying
TX考了好多awk的东西
作者:
wayflying
时间:
2014-09-02 13:54
估计是面试游戏运维。
回复
28#
stupid_lee
作者:
super皮波
时间:
2014-09-02 13:57
回复
28#
stupid_lee
你面试的是什么岗位?
作者:
wayflying
时间:
2014-09-02 14:01
一般笔试awk,我觉得会求和和算平均值就够了(小数点保留2位置)。
剩下的,工作实践中自己再去慢慢搞。
作者:
reb00t
时间:
2014-09-02 14:32
php练习来了。
<?php
$fa = file('200.txt');
$newarr=array();
foreach ($fa as $k => $v) {
$arr=explode(" ", preg_replace("/[ ]+/"," ", $v));
if ($arr[1]>40 || $arr[1]<30) {
$newarr[$arr[0]." ".$arr[1]]+=$arr[2];
}
}
foreach ($newarr as $kk=> $vv) {
echo $kk." ".$vv."\n";
}
?>
结果:
123456 23 1000
345678 21 4679
456789 45 4532
复制代码
作者:
love_shift
时间:
2014-09-02 15:39
目测一下,做个练习
root@ubuntu:~/cu_test# more t.py
#!/usr/bin/env python
#
#v2.7
def getData(fname):
with open(fname,'r') as f:
s = f.read().strip().split('\n')
return s
def dataJudge():
container = {}
fd_list = getData('file')
for item in fd_list:
k = [ int(x) for x in item.split()]
if k[1] < 30 or k[1] > 40:
if k[0] in container.keys():
container[k[0]][2] += k[2]
else:
container[k[0]] = k
for i,v in container.items():
print ' '.join([ str(x) for x in v ])
if __name__ == '__main__':
dataJudge()
root@ubuntu:~/cu_test# ./t.py
123456 23 1000
456789 45 4532
345678 21 4679
root@ubuntu:~/cu_test# more file
123456 23 1000
234567 34 1234
345678 21 1234
456789 45 4532
234567 34 1233
234567 34 1234
345678 21 3445
复制代码
作者:
cao627
时间:
2014-09-02 15:47
回复
1#
stupid_lee
123456 23 1000
123456 24 1000
你的数据中会不会有如上情况出现,即123456这个ID在23级中花费了1000s,在24级中也花了1000s,那么这个ID共花了2000s不是吗。
作者:
reb00t
时间:
2014-09-02 15:53
回复
33#
love_shift
哈哈 ,顶楼上,以后我写php,你写python吧~~ 气氛搞起。
作者:
stupid_lee
时间:
2014-09-02 16:15
回复
34#
cao627
这个 级别是实时的,所以和ID一一对应
作者:
stupid_lee
时间:
2014-09-02 22:16
回复
33#
love_shift
我只能45度角,仰望天空了
作者:
henianen22
时间:
2014-09-03 12:34
上个星期去了,有这题,awk '$2<30 || $2>40{a[$1]+=$3;b[$1]=$2}END{for(i in a)print i,b[i],a[i]}' k.txt
作者:
Kasiotao
时间:
2014-09-03 14:55
awk '{if($2<30 || $2>40)next;a[$1" "$2]+=$3}END{for(i in a){print i,a[i]}}' testfile
复制代码
作者:
Nathon99
时间:
2014-09-04 17:27
回复
3#
Herowinter
{a[$1" "$2]+=$3}
这个是什么意思呢?
作者:
Herowinter
时间:
2014-09-04 19:35
回复
40#
Nathon99
a[$1" "$2]=a[$1" "$2]+$3
在前面累积的计数上加上当前第3列的值。
作者:
wuxiaobo_2009
时间:
2014-09-11 13:07
回复
3#
Herowinter
明显误读了 第三个条件
作者:
Herowinter
时间:
2014-09-11 13:16
回复
42#
wuxiaobo_2009
楼主的需求和示例文本里没说对于这种情况怎么处理:
345678 21 1234
345678 22 3456
即$1一样,$2不一样时怎么处理。对我来说这个算是一个
未定义行为,我只是按自己的理解实现了下,只处理前2列
都一样的文本,有出入莫怪。
作者:
wuxiaobo_2009
时间:
2014-09-11 13:34
回复
19#
Shell_HAT
3701 为什么说明不对呢?
作者:
baoersc
时间:
2014-09-11 15:07
回复
3#
Herowinter
高手,我捣鼓半天都没有下文呢。对字符下标数组理解不够。
作者:
ziyunfei
时间:
2014-09-12 13:02
这面试题也太简单了
作者:
酋长海布里
时间:
2014-09-12 14:12
回复
41#
Herowinter
数组下标是
$1" "$2
怎么理解?
作者:
stupid_lee
时间:
2014-09-12 15:32
回复
43#
Herowinter
不好意思是我没讲清楚,不过原题和你理解的是一样的,第二列的级别是实时的,因此第一列相同,第二列则也就相同了。
哪些误解题目的人们,就当是多练习了一下下吧,我相信不管怎么变Herowinter一分钟内肯定都能搞定的
作者:
李满满
时间:
2014-09-12 15:57
学生党:飘过~
[yhsafe@b10-1b ~]$ awk '$2<30||$2>40{b[$1]=$2;a[$1]=(a[$1]=="")?$3:a[$1]+$3}END{for(x in a){print x,b[x],a[x]}}' yhsafe.txt
123456 23 1000
456789 45 4532
345678 21 4679
作者:
聆雨淋夜
时间:
2014-11-10 20:48
awk '{if($2>30&&$2<40)next}{a[$1"\t"$2]=a[$1"\t"$2]+$3}END{for(i in a)print i,a[i]}' file
作者:
wiliiwin
时间:
2014-11-11 17:50
本帖最后由 wiliiwin 于 2014-11-11 18:16 编辑
python来一发
#!/usr/bin/python
def getConfig():
f = open("29.txt","r")
dic = {}
key = ()
for line in f:
line = line.strip()
line = line.split()
if int(line[1])<30 or int(line[1])>40:
key = (line[0],line[1])
if key in dic:
dic[key]= dic[key]+int(line[2])
else:
dic[key] = int(line[2])
for keys in dic.keys():
print keys[0],keys[1],dic[keys]
if __name__ == '__main__':
getConfig()
复制代码
# 3.py
456789 45 4532
123456 23 1000
345678 21 4679
复制代码
作者:
love_shift
时间:
2014-11-12 22:56
这道题为什么这么火, 练习下。
#!/usr/bin/env python
#
#python 2.7
from fileinput import input
d = {}
for l in input('tmp'):
n = [ int(x) for x in l.split() ]
if n[1] < 30 or n[1] > 40:
if n[0] in d.keys():
d[n[0]][1] += n[2]
else:
d[n[0]] = n[1:]
for k,v in d.items():
print '{}\t{}\t{}'.format(k,v[0],v[1])
复制代码
root@ubuntu:/tmp# python t.py
123456 23 1000
456789 45 4532
345678 21 4679
复制代码
作者:
linuxboy823
时间:
2014-11-14 09:43
$ awk '{if($2<30||$2>40) a[$2]++;}END{for (i in a) print $1,i,a[i]}' urfile3
345678 21 2
345678 23 1
345678 45 1
作者:
linuxboy823
时间:
2014-11-14 09:45
awk '{if($2<30||$2>40) a[$2]+=$3;}END{for (i in a) print $1,i,a[i]}' urfile3
345678 21 4679
345678 23 1000
345678 45 4532
作者:
linuxboy823
时间:
2014-11-14 09:45
awk '{if($2<30||$2>40) a[$2]+=$3;}END{for (i in a) print $1,i,a[i]}' urfile3
345678 21 4679
345678 23 1000
345678 45 4532
作者:
linuxboy823
时间:
2014-11-14 09:47
$ awk '{if($2<30||$2>40) a[$1]+=$3;}END{for (i in a) print $1,i,a[i]}' urfile3
345678 123456 1000
345678 345678 4679
345678 456789 4532
欢迎光临 Chinaunix (http://bbs.chinaunix.net/)
Powered by Discuz! X3.2