当前位置:Linux教程 - Shell - shell - 合并某些行

shell - 合并某些行

合并某些行
2004-04-23 15:18 pm
来自:Linux文档
现载:Www.8s8s.coM
地址:无名

例如有test.txt文件
1 aaa 1000
2 bbb 1000
3 aaa 1000
4 aaa 1000
5 ccc 1000
6 bbb 1000
要求产生新文件格式为
1 aaa 3000
2 bbb 2000
5 ccc 1000

写的有些复杂,我也没什么好方法

#!/usr/bin/ksh
awk '{print $2 }' 1.txt | sort -u > ./1.txt.tmp

while read keyword
do
keyno=0
keyvalue=0
grep $keyword 1.txt | while read no nouse value
do
if [ $keyno -ge $no -o $keyno -eq 0 ]
then
keyno=$no
fi
(( keyvalue=keyvalue + value ))
done
echo "$keyno $keyword $keyvalue"
done<1.txt.tmp > 2.txt

rm -f ./1.txt.tmp

echo "aaa `cat test.txt|awk '{if($1~/aaa/) print $2}'|awk '{kkk+=$1}END{printf "%9.2f" , kkk}'`" > test.out
echo "bbb `cat test.txt|awk '{if($1~/bbb/) print $2}'|awk '{kkk+=$1}END{printf "%9.2f" , kkk}'`" >> test.out
echo "ccc `cat test.txt|awk '{if($1~/ccc/) print $2}'|awk '{kkk+=$1}END{printf "%9.2f" , kkk}'`" >> test.out

biansj,你的程序不是不行,bsh可以吗?

一面字我打错了,程序不能运行,bsh可以吗?

编辑  发贴时间2002/12/14 09:48am 此 IP 为代理服务器IP: 已设置保密
该用户目前不在线 nhrms

去掉第一行:
awk '{print $2 }' 1.txt | sort -u > ./1.txt.tmp

while read keyword
do
keyno=0
keyvalue=0
grep $keyword 1.txt | while read no nouse value
do
if [ $keyno -ge $no -o $keyno -eq 0 ]
then
keyno=$no
fi
(( keyvalue=keyvalue + value ))
done
echo "$keyno $keyword $keyvalue"
done<1.txt.tmp > 2.txt

rm -f ./1.txt.tmp

运行后提示:
+:not found

#!/usr/bin/bsh
awk '{print $2 }' 1.txt | sort -u > ./1.txt.tmp

while read keyword
do
keyno=0
keyvalue=0
grep $keyword 1.txt | while read no nouse value
do
if [ $keyno -ge $no -o $keyno -eq 0 ]
then
keyno=$no
fi
keyvalue=`expr $keyvalue + $value`
#(( keyvalue=keyvalue + value ))
done
echo "$keyno $keyword $keyvalue"
done<1.txt.tmp > 2.txt

rm -f ./1.txt.tmp

运行后,输出:
0 aaa 0
0 bbb 0
0 ccc 0
不对!

你把我写的内容C&P一个文件file,chmod +x file,然后运行./file
注意1.txt要在当前目录,结果为2.txt,如果不对,我就不清楚了

我刚才就是这么做的,出来结果就这样

改成这样就可以了。

代码:



awk '{print $2 }' test.txt | sort -u > ./1.txt.tmp

while read keyword
do
keyno=0
keyvalue=0
grep $keyword test.txt > 2.txt.tmp
while read no nouse value
do
if [ $keyno -ge $no -o $keyno -eq 0 ]
then
keyno=$no
fi
keyvalue=`expr $keyvalue + $value`
done < 2.txt.tmp
echo "$keyno $keyword $keyvalue"
done <1.txt.tmp

rm -f ./[12].txt.tmp

环境为PC SOLARIS 7。
上边的还是执行不了,俺看一下,原来在执行
awk '{print $2 }' test.txt | sort -u > ./1.txt.tmp 时,产生的文件 1.txt.tmp
的头两行为空格,导致脚本执行不好。俺把那行改一下,变为两行:
-------------------------------------------------
awk '{print $2 }' 1.txt | sort -u > ./1.txt.temp
grep -v "^ *$" 1.txt.temp > 1.txt.tmp
------------------------------------------------
执行正常:
------------------------------------------------
# ./sortnadd
0+1 aaa 3000
0+2 bbb 2000
0+5 ccc 1000
-----------------------------------------------
哪位高手指点一下,为何有空行?

0+1 aaa 3000

0+1 啥子意思?

楼上贴子作废啊,SORRY,我自己把自己骗了

楼上各位有考虑过如果原始数据量很大(比如5万条、50万条?)时执行效率的问题吗?
如果处理每个关键字都要扫描一下源文件的话似乎太慢了?
#!/bin/sh
sort +1 -2 test.txt > 1.txt
awk 'BEGIN{no=-1;}{if (no==-1){no=$1;k=$2;tot=0;}
if (k==$2) {tot+=$3;}
else{printf "%d %s %d ", no,k,tot;
no=$1; k=$2; tot=$3;} }
END{printf "%d %s %d ", no,k,tot;}' 1.txt > output.txt
rm -f 1.txt

sort +1 -2 啥子意思?

http://www.fanqiang.com/a1/b5/20010923/0805001336.html

这个问题的本质还是分组求和问题,第一个自定相对来说无甚含义,因此我简单的给出下面的答案:
awk '{total[$2]+=$3}END{for (s in total){printf("%s %d ",s,total[s])}' 1.txt

斑竹,这是什么shell?ksh 好象不可以

下面引用由红豆在 2002/12/16 01:17am 发表的内容:
改成这样就可以了。
awk '{print $2 }' test.txt | sort -u > ./1.txt.tmp
while read keyword
do
...

为什么运行后 总是

0 aaa 0
0 bbb 0
0 ccc 0

哪里不可以?
这是awk的问题,如果你引号用的对的话,有shell无关。