LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1136|回复: 11

关于数字

[复制链接]
发表于 2007-7-2 10:32:58 | 显示全部楼层 |阅读模式
在下列一组数字中,用什么方法能求出,在这一组数字中  少   了哪些数字,并列到一个新表当中

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
发表于 2007-7-2 20:15:35 | 显示全部楼层
分析:

这个文件包含一串数字,1-10的格式是0?

似乎是在WIN下生成的文件,因为是以\r\n为分行符的

先用sort生成唯一的数字列表
[color="Red"]sort -n -u 数字.txt > 1.txt
然后将\r\n 转换成 \n
[color="Red"]sed -i s@^M@@ 1.txt   [color="Blue"]注:^M是通过ctrl+VM来输入的

然后找到1.txt中的最大值
maxvalue=$(tail -n 1 1.txt)

然后再生成一个从1-maxvalue的数字的列表文件
[color="Red"]seq -w 1 10 > 2.txt
seq 11 $(tail -n 1 1.txt) >> 2.txt

然后比较 1.txt 和 2.txt
[color="Red"]diff 1.txt 2.txt | grep '^>' | awk '{ print $2 }'
这样就能够获取缺少的数字了

最终代码
  1. sort -n -u 数字.txt > 1.txt
  2. sed -i s@^M@@ 1.txt
  3. seq -w 1 10 > 2.txt
  4. seq 11 $(tail -n 1 1.txt) >> 2.txt
  5. diff 1.txt 2.txt | grep '^>' | awk '{ print $2 }' > 缺少的数字.txt
  6. rm -f 1.txt 2.txt
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-7-2 20:57:09 | 显示全部楼层
不明白。
004这样的类型算不算少?
回复 支持 反对

使用道具 举报

发表于 2007-7-2 21:45:50 | 显示全部楼层
不要说我灌水,刚才在windows powershell作了个解决办法。
  1. cat seq.txt | sort {[int]$_}  -unique | % {$i = 1} {while ($i -lt $_) {$i;$i++
  2. }; $i++}
复制代码

这个办法无所谓开头是否有0,有多少个0。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-7-4 11:35:15 | 显示全部楼层
Post by seamonkey
不要说我灌水,刚才在windows powershell作了个解决办法。
  1. cat seq.txt | sort {[int]$_}  -unique | % {$i = 1} {while ($i -lt $_) {$i;$i++
  2. }; $i++}
复制代码

这个办法无所谓开头是否有0,有多少个0。
然后比较 1.txt 和 2.txt
[color="Red"]diff 1.txt 2.txt | grep '^>' | awk '{ print $2 }'
这样就能够获取缺少的数字了


diff 这一步错了

提示:command not found

seamonkey 的在windows下的方法,通过了,谢谢大家


不过我很想知道在linux下的解决方法
回复 支持 反对

使用道具 举报

发表于 2007-7-4 12:54:45 | 显示全部楼层
裸用awk:

  1. awk 'BEGIN{t=0} {v=$1+0;if(t<v){ for(i=t+1;i<v;i++){a[i]=i;}; t=v}else if(a[v]) delete a[v]} END{for (i=1;i<t;i++) if(a[i])print a[i]} 文件
复制代码
回复 支持 反对

使用道具 举报

发表于 2007-7-4 21:17:31 | 显示全部楼层
因为这个文件中包含\r\n,所以

sort -n -u 数字.txt | sed s@^M@@ | (a=1;while read b ;do for((;a<b;a++));do echo $a;done;((a++));done) 2>/dev/null > 新数字.txt

解释:

sort -n -u 表示按照数字方式排序,如果有重复的则去除重复的部分
sed s@^M@@表示将\r这个字符删除,^M是通过按ctrl+VM获取的,也可以用\\r来代替

a=1;while read b ;do for((;a<b;a++));do echo $a;done;((a++));done
先设置初始值a=1,然后从标准输入中读一个字符串(数值型的)b
从a到b进行循环,并打印a的值,如果a和b之间有差值,那么就会打印出那些缺少的数字
循环结束后,a与b的值相同,因此需要把a的值增加1 ((a++))

>/dev/null 是把错误不输出,因为有这两个数08 09 在bash中,把有前导0的值作为8进制来处理,因此,08 09就不是合理的数值了,因此,会有错误输出,不过不影响结果(如果只出现09,而没有08的情况下,会出现缺省结果中少一个8,对这个错误,不知道该如何用简单的方式来处理 )

> 新数字.txt   表示将结果输出到新的文件中

[color="Red"]注:脚本运行环境:debian testing [GNU bash, version 3.1.17(1)-release (i486-pc-linux-gnu)]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-7-5 11:11:18 | 显示全部楼层
回复:springwind426

真的很感谢您能在百忙之中,抽出您的宝贵时间来。
我的系统是F7,做出以上您的测试都没有通过,原因一直没有找出来

这次不同于上次的是,没有任何报错,都很正常,但最后输出的文件内容是空的

不过还是要感谢您的!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2007-7-5 11:13:07 | 显示全部楼层
回复:lastart

裸用AWK不执行结果,我是直接COPY你的代码的,只加了一个最后面的文件名

其余正常,回车后出现 > 号之后没反应了


非常感谢您的关注
回复 支持 反对

使用道具 举报

发表于 2007-7-5 16:12:42 | 显示全部楼层
Post by linux1213
回复:springwind426

真的很感谢您能在百忙之中,抽出您的宝贵时间来。
我的系统是F7,做出以上您的测试都没有通过,原因一直没有找出来

这次不同于上次的是,没有任何报错,都很正常,但最后输出的文件内容是空的

不过还是要感谢您的!


如果输出的文件为空,试试

sort -n -u 数字.txt | sed s@^M@@ | (a=1;while read b ;do for((;a<b;a++));do echo $a;done;((a++));done)

就是把最后的重定向语句去掉,是不是你的bash不支持某些特性,而导致有错误,但是因为将错误输出掩盖了(2>/dev/null),所以你可以去掉这个试试

------------------------------
awk 'BEGIN{t=0} {v=$1+0;if(t<v){ for(i=t+1;i<v;i++){a=i;}; t=v}else if(a[v]) delete a[v]} END{for (i=1;i<t;i++) if(a)print a}'  文件
注,他的那个代码在最后一个}后面少了一个'(单引号),用他的代码是可以的,而且没有任何错误提示
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表