【求】按字母用量排序算法

sh/bash/dash/ksh/zsh等Shell脚本
回复
waynehu
帖子: 48
注册时间: 2008-11-04 17:44

【求】按字母用量排序算法

#1

帖子 waynehu » 2011-03-23 18:23

列表的内容是即将要到期,我可以抢注的域名
我想用脚本帮我过滤,把比较好的域名排序到文本的最上面,然后我可以比较方便找到值得注册的域名

我要的是排序,但不是按首字母排序,而是按用到的字母数量排序
关于长度的问题,不同长度的域名抢注难度差很大,所以我已经事先都处理了,把一样长度的域名都过滤到一起来横向比较,所以每行长度都是一样的
比如我提供的100行测试数据,假设里面其中有1行是“aaaaaaa.com”,这个域名明显要好于另一行的“adkrfid.com”因为前者用到的字母数量是1(只有“a”一个字母被用到),而后者用了6个字母(其中“d”用了2次)

所以在排序方面,我希望按 用到字母的数量 来排序,而不是按首字母排序
排序完的结果类似于

代码: 全选

aaaaaaa.com
ffffdff.com
xsxsxss.com
fieiiee.com
adkrfid.com

因为上面他们用到字母数分别为1,2,2,3,6个字母
-----------------------------------------------------------------------以下为我的思路


我的思路是写一段shell,来分析每一行,并在行首写上出现数比如abcca就变成3abcca,而abaab就变成2abaab
再进行sort排序,最后把开头的数字全部去掉
考虑到会出现10abcdefghjk的情况,所以如果数量大于10,全部标为0abcdefghjk,然后先删掉0开头的所有行再用sort排序
因为域名里出现10个以上的字母的情况基本可以视为垃圾域名了

还有关于计算字母数量,我有个想法,但不会实现,先把字符串排序,然后去除重复的,最后计算字符串长度,如:
ubuntu.com --字符串排序-> bntuuu.com --去除重复-> bntu.com --计算字符串长度-> length(bntu) -> 4




请各位帮我想想有没有更好的方法来实现我的要求,谢谢啦!

提供一段百行代码做测试,长度均为7(不算.com)

代码: 全选

almabon.com
alnawal.com
allowat.com
allenav.com
alkanpc.com
aliumus.com
aliciat.com
albumer.com
alawaar.com
alfrdos.com
alfanix.com
alhejas.com
alaawar.com
akawife.com
aisihua.com
akadeli.com
afducts.com
afannin.com
aerobec.com
aerodeo.com
aepteam.com
aeraces.com
agcgold.com
agapide.com
agetake.com
afrivid.com
ahcards.com
ahtians.com
aifulai.com
agpifer.com
airjoey.com
aijiahm.com
ayocool.com
aypinar.com
aygazsu.com
axitrax.com
ayabadu.com
awarewe.com
awnnews.com
awotomo.com
awpulsa.com
awryday.com
awbyrde.com
avondns.com
avriziv.com
avarasa.com
aucionm.com
attvoip.com
atudoor.com
atlguru.com
atohuna.com
athrock.com
assurey.com
aslikal.com
aspinoy.com
aspocam.com
asproot.com
askcris.com
askcrom.com
askltci.com
askltcr.com
asanitx.com
ashaicg.com
ashivji.com
arwclan.com
artwhit.com
amabrpc.com
artmeco.com
alwafad.com
altlila.com
alrameh.com
alqrarh.com
boulund.com
boshaai.com
boskina.com
bookrec.com
bonggat.com
boobkle.com
bodycea.com
boernuo.com
bogeytv.com
boinged.com
bodfund.com
azamint.com
bsmmove.com
btobink.com
btocall.com
brunosr.com
brklynd.com
brhsoft.com
boxlace.com
bpmsoul.com
cowsoul.com
coutsbk.com
coupare.com
costarj.com
cotelab.com
coreejb.com
corbinm.com
coopnan.com
上次由 waynehu 在 2011-03-23 23:46,总共编辑 2 次。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 求正则表达式

#2

帖子 fnan » 2011-03-23 22:08

把对应行号的内容再打印出来不难,有需要的话。

代码: 全选

kose5@kose5-Aspire-4552:~$ while read fl ; do l=${fl%.*}; while [[ -n $(echo $l|grep '\([^ ]\).*\1') ]];do l=$(echo $l|sed 's/\([^ ]\)\(.*\)\1/\1\2/g'); done; echo $l; done < com.t|awk '{print length($0),NR|"sort -n"}'|awk 'BEGIN{printf "%-15s %s\n", "最小字母数", "行号"} {if (NR > 1 && last != $1) exit; last = $1; printf "%-20s %s\n", $1, $2}'
最小字母数           行号
4                    13
4                    18
4                    2
4                    38
4                    46
4                    70
4                    9
kose5@kose5-Aspire-4552:~$ 
上次由 fnan 在 2011-03-24 4:02,总共编辑 2 次。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
waynehu
帖子: 48
注册时间: 2008-11-04 17:44

Re: 求正则表达式

#3

帖子 waynehu » 2011-03-23 23:11

fnan 写了:对lz的要求有些不明,比如域名前加数字再拿掉干什么?大于十的数字拿掉也意义不大, 如果最小字母数是十如何?再有找出最小字母的域名后怎样?
写个通用的, 域名字数不限:
awk '{sub(/.com/,""); "echo " $0 "|tr -s [:alpha:]"|getline l;print length(l),NR|"sort -n"}' com.t|awk 'BEGIN{printf "%-25s %s\n", "最小字母数", "行号"} {if (NR > 1 && last != $1) exit; last = $1; printf "%-20s %s\n", $1, $2}'

谢谢你的代码
关于你看不懂的问题可能是因为我写的比较急(下班前写的),所以没有说清楚
不过我已经重新编辑过顶楼了,我觉得应该说清楚了,如果有空再帮我看看吧
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 【求】按字母用量排序算法

#4

帖子 fnan » 2011-03-24 5:52

实用版:

代码: 全选

kose5@kose5-Aspire-4552:~$ file_name="com.t"; while read fl ; do l=${fl%.*}; while [[ -n $(echo $l|grep '\([^ ]\).*\1') ]];do l=$(echo $l|sed 's/\([^ ]\)\(.*\)\1/\1\2/g'); done; echo $l; done < $file_name|awk '{print length($0),NR|"sort -n"}'|awk '{if (NR > 1 && last != $1) exit; last = $1; printf "%s %s\n", $1, $2}'|while read nl;do pl=${nl#* }; cmd=$pl'q;d'; echo; echo -n "最小字母数 ${nl% *}   文本 中行号 $pl >>>> 域名 "; sed $cmd $file_name; echo; done

最小字母数 4   文本中行号 13 >>>> 域名 alaawar.com


最小字母数 4   文本中行号 18 >>>> 域名 afannin.com


最小字母数 4   文本中行号 2 >>>> 域名 alnawal.com


最小字母数 4   文本中行号 38 >>>> 域名 awarewe.com


最小字母数 4   文本中行号 46 >>>> 域名 avarasa.com


最小字母数 4   文本中行号 70 >>>> 域名 altlila.com


最小字母数 4   文本中行号 9 >>>> 域名 alawaar.com

kose5@kose5-Aspire-4552:~$ 
始终无法解决awk中使用sed高级功能问题,使用fifo文件的话机构复杂,awk速度快n倍。
关键功能显示:

代码: 全选

kose5@kose5-Aspire-4552:~$ l="asiasiasiaaaasssshhhh.com"; l=${l%.*}; n=0; while [[ -n "$(echo $l|grep '\([^ ]\).*\1')" ]]; do l=$(echo $l|sed 's/\([^ ]\)\(.*\)\1/\1\2/g'); ((n++)); echo "第 $n 次循环> $l"; done
第 1 次循环> asiasiasiaaassshhh
第 2 次循环> asiasiasiaasshh
第 3 次循环> asiasiasiash
第 4 次循环> asiasiasish
第 5 次循环> asiasisih
第 6 次循环> asisiih
第 7 次循环> asiih
第 8 次循环> asih
kose5@kose5-Aspire-4552:~$ 
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
sk1418
帖子: 229
注册时间: 2007-07-01 17:36
系统: (En):System
来自: (En):address
联系:

Re: 【求】按字母用量排序算法

#5

帖子 sk1418 » 2011-03-24 8:13

截取了你那100个网站其中几个作为例子,存成sites.txt。 然后执行下面的命令(需要gawk)

代码: 全选

sed 's/\.com//g' sites.txt|awk -F '' '{delete a; for (i=1;i<=NF;i++)a[$i]=1; b[NR]=length(a)":"$0;} END{for(i=1;i<=length(b);i++) print b[i]".com"}' | sort  -nt":" -k1
输出:

代码: 全选

4:avarasa.com
4:awarewe.com
5:aslikal.com
5:avriziv.com
5:awnnews.com
5:awotomo.com
5:awryday.com
5:axitrax.com
5:ayabadu.com
5:ayocool.com
6:askcris.com
6:aspocam.com
6:asproot.com
6:assurey.com
6:atlguru.com
6:atohuna.com
6:attvoip.com
6:atudoor.com
6:avondns.com
6:awpulsa.com
6:aygazsu.com
6:aypinar.com
7:aspinoy.com
7:athrock.com
7:aucionm.com
7:awbyrde.com
这个没什么算法不算法的,就一个文本处理罢了,当然你要编程实现另说

步骤:
先sed去掉.com,
然后形成 (字母数:域名.com)的格式,
最后用sort排序

---
开始想就用awk的asort就得了,结果没发现asort如何按照数字来排,弄的10:比2:还靠前。。。还是用sort得了。懒得再折腾awk那些数组了。

如果你不需要前面那个数字,自己用sed 或者cut弄下去就可以了。

不知道这个满足你需要不?
---
regards,

Kent
waynehu
帖子: 48
注册时间: 2008-11-04 17:44

Re: 【求】按字母用量排序算法

#6

帖子 waynehu » 2011-03-24 9:47

楼上的好强大,但length数组不是很清楚,能否解释一下,谢谢
我已经测试知道了,$i的值并不是i的值,而是每个域的值,真是个好办法阿!

代码: 全选

awk -F ''                           //个人猜测是否以空 '' 来作为分隔符,使每一个字母都是一个域
'{
delete a;                                   //删除每行循环时产生的a数组
for (i=1;i<=NF;i++)a[$i]=1;      //NF应该为7(个字母),这行是把数组a[1]到a[7]都赋值为1
b[NR]=length(a)":"$0;                 //这句里的length(a)不懂,不是计算数组长度吗,那应该统一是7啊?(已经解决)
}‘

fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 【求】按字母用量排序算法

#7

帖子 fnan » 2011-03-24 10:22

sk1418妙用数组下标,有学到了,作为练习,写了个同样原理不同版本的awk:
kose5@kose5-Aspire-4552:~$ awk -F"." '{delete a2;l=split($1,a1,""); for (i in a1)a2[a1]=1; b[NR]=length(a2)":"$0;} END{for(i in b) print b}' com.t| sort -n
4:afannin.com
4:alaawar.com
4:alawaar.com
4:alnawal.com
4:altlila.com
4:avarasa.com
4:awarewe.com
5:aepteam.com
5:aeraces.com
5:aerodeo.com
5:agetake.com
5:aifulai.com
5:aijiahm.com
5:aisihua.com
5:aliciat.com
5:allenav.com
5:allowat.com
5:alqrarh.com
5:alwafad.com
5:aslikal.com
5:avriziv.com
5:awnnews.com
5:awotomo.com
5:awryday.com
5:axitrax.com
5:ayabadu.com
5:ayocool.com
5:boobkle.com
5:coopnan.com
6:aerobec.com
6:afrivid.com
6:agapide.com
6:agcgold.com
6:ahcards.com
6:ahtians.com
6:akadeli.com
6:akawife.com
6:alfanix.com
6:alhejas.com
6:aliumus.com
6:alkanpc.com
6:almabon.com
6:alrameh.com
6:amabrpc.com
6:artwhit.com
6:arwclan.com
6:asanitx.com
6:ashaicg.com
6:ashivji.com
6:askcris.com
6:aspocam.com
6:asproot.com
6:assurey.com
6:atlguru.com
6:atohuna.com
6:attvoip.com
6:atudoor.com
6:avondns.com
6:awpulsa.com
6:aygazsu.com
6:aypinar.com
6:azamint.com
6:bodfund.com
6:boernuo.com
6:bonggat.com
6:bookrec.com
6:boshaai.com
6:boulund.com
6:brunosr.com
6:bsmmove.com
6:btobink.com
6:btocall.com
6:coreejb.com
6:cowsoul.com
7:afducts.com
7:agpifer.com
7:airjoey.com
7:albumer.com
7:alfrdos.com
7:artmeco.com
7:askcrom.com
7:askltci.com
7:askltcr.com
7:aspinoy.com
7:athrock.com
7:aucionm.com
7:awbyrde.com
7:bodycea.com
7:bogeytv.com
7:boinged.com
7:boskina.com
7:boxlace.com
7:bpmsoul.com
7:brhsoft.com
7:brklynd.com
7:corbinm.com
7:costarj.com
7:cotelab.com
7:coupare.com
7:coutsbk.com
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
头像
trigger
帖子: 1604
注册时间: 2006-10-25 18:08

Re: 【求】按字母用量排序算法

#8

帖子 trigger » 2011-03-24 11:13

这个不需要什么算法,就是个字符串操作,不用awk也行的
for i in `cat t001`;do echo -n "$i " && echo ${i:0:7}|grep -o '[a-z]'|sort -u|wc -l;done
almabon.com 6
alnawal.com 4
allowat.com 5
allenav.com 5
alkanpc.com 6
aliumus.com 6
aliciat.com 5
albumer.com 7
alawaar.com 4
alfrdos.com 7
alfanix.com 6
alhejas.com 6
alaawar.com 4
akawife.com 6
aisihua.com 5
akadeli.com 6
afducts.com 7
afannin.com 4
aerobec.com 6
aerodeo.com 5
aepteam.com 5
aeraces.com 5
agcgold.com 6
agapide.com 6
agetake.com 5
afrivid.com 6
ahcards.com 6
ahtians.com 6
aifulai.com 5
agpifer.com 7
airjoey.com 7
aijiahm.com 5
ayocool.com 5
aypinar.com 6
aygazsu.com 6
axitrax.com 5
ayabadu.com 5
awarewe.com 4
awnnews.com 5
awotomo.com 5
awpulsa.com 6
awryday.com 5
awbyrde.com 7
avondns.com 6
avriziv.com 5
avarasa.com 4
aucionm.com 7
attvoip.com 6
atudoor.com 6
atlguru.com 6
atohuna.com 6
athrock.com 7
assurey.com 6
aslikal.com 5
aspinoy.com 7
aspocam.com 6
asproot.com 6
askcris.com 6
askcrom.com 7
askltci.com 7
askltcr.com 7
asanitx.com 6
ashaicg.com 6
ashivji.com 6
arwclan.com 6
artwhit.com 6
amabrpc.com 6
artmeco.com 7
alwafad.com 5
altlila.com 4
alrameh.com 6
alqrarh.com 5
boulund.com 6
boshaai.com 6
boskina.com 7
bookrec.com 6
bonggat.com 6
boobkle.com 5
bodycea.com 7
boernuo.com 6
bogeytv.com 7
boinged.com 7
bodfund.com 6
azamint.com 6
bsmmove.com 6
btobink.com 6
btocall.com 6
brunosr.com 6
brklynd.com 7
brhsoft.com 7
boxlace.com 7
bpmsoul.com 7
cowsoul.com 6
coutsbk.com 7
coupare.com 7
costarj.com 7
cotelab.com 7
coreejb.com 6
corbinm.com 7
coopnan.com 5
楼主真是一派胡言,真可谓:“两个黄鹂鸣翠柳,不知所云;一行白鹭上青天,不知所止“。本来不想和你辩论,今天气愤不过,和你理论一番。我国宪法写得清清楚楚:“一夜夫妻百日恩,七楼以上才有电梯”。这个想必你知道,既然知道,你就不能断章取义,就算是天气预报,它还有不准的时候呢!!!再者说了,那中国银行也不是你一家开的。人家马拉多纳都结婚了,你还拿着粮票顶什么用呢。真是滑天下之大稽。前些日子,全国人大刚刚开过会,郑重声明:“中国不搞多party制,存栏母猪给补贴”。多好的事呢,楞让你这号人给搅混了。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 【求】按字母用量排序算法

#9

帖子 fnan » 2011-03-24 11:55

这个grep -o功能找了好久了。
kose5@kose5-Aspire-4552:~$ for i in `cat com.t`;do echo -n "$i ";echo $i|cut -d"." -f1|grep -o '[^ ]'|sort -u|wc -l;done|sort -n -k2
afannin.com 4
alaawar.com 4
alawaar.com 4
alnawal.com 4
altlila.com 4
avarasa.com 4
awarewe.com 4
aepteam.com 5
aeraces.com 5
aerodeo.com 5
agetake.com 5
aifulai.com 5
aijiahm.com 5
aisihua.com 5
aliciat.com 5
allenav.com 5
allowat.com 5
alqrarh.com 5
alwafad.com 5
aslikal.com 5
avriziv.com 5
awnnews.com 5
awotomo.com 5
awryday.com 5
axitrax.com 5
ayabadu.com 5
ayocool.com 5
boobkle.com 5
coopnan.com 5
aerobec.com 6
afrivid.com 6
agapide.com 6
agcgold.com 6
ahcards.com 6
ahtians.com 6
akadeli.com 6
akawife.com 6
alfanix.com 6
alhejas.com 6
aliumus.com 6
alkanpc.com 6
almabon.com 6
alrameh.com 6
amabrpc.com 6
artwhit.com 6
arwclan.com 6
asanitx.com 6
ashaicg.com 6
ashivji.com 6
askcris.com 6
aspocam.com 6
asproot.com 6
assurey.com 6
atlguru.com 6
atohuna.com 6
attvoip.com 6
atudoor.com 6
avondns.com 6
awpulsa.com 6
aygazsu.com 6
aypinar.com 6
azamint.com 6
bodfund.com 6
boernuo.com 6
bonggat.com 6
bookrec.com 6
boshaai.com 6
boulund.com 6
brunosr.com 6
bsmmove.com 6
btobink.com 6
btocall.com 6
coreejb.com 6
cowsoul.com 6
afducts.com 7
agpifer.com 7
airjoey.com 7
albumer.com 7
alfrdos.com 7
artmeco.com 7
askcrom.com 7
askltci.com 7
askltcr.com 7
aspinoy.com 7
athrock.com 7
aucionm.com 7
awbyrde.com 7
bodycea.com 7
bogeytv.com 7
boinged.com 7
boskina.com 7
boxlace.com 7
bpmsoul.com 7
brhsoft.com 7
brklynd.com 7
corbinm.com 7
costarj.com 7
cotelab.com 7
coupare.com 7
coutsbk.com 7

如果是数百万个以上域名的话,用awk不一样的。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
fnan
帖子: 919
注册时间: 2009-07-01 22:04

Re: 【求】按字母用量排序算法

#10

帖子 fnan » 2011-03-24 12:00

开始想就用awk的asort就得了,结果没发现asort如何按照数字来排,弄的10:比2:还靠前。。。还是用sort得了。懒得再折腾awk那些数组了。
发现asort函数有bug,字母排序也不行。
bash不如perl精妙,学不到lisp的皮毛,远不够c++强悍,不过可以用。
头像
lilydjwg
论坛版主
帖子: 4249
注册时间: 2009-04-11 23:46
系统: Arch Linux
联系:

Re: 【求】按字母用量排序算法

#11

帖子 lilydjwg » 2011-03-24 14:14

[bash]
python3 -c 'import sys
l = [x[:-5] for x in sys.stdin.readlines()]
l.sort(key=lambda x: len(set(x)))
for i in l: print(i+".com")' < yourfile
[/bash]
:em04
tusooa
帖子: 6548
注册时间: 2008-10-31 22:12
系统: 践兔
联系:

Re: 【求】按字母用量排序算法

#12

帖子 tusooa » 2011-03-27 13:02

统计用字个数好办。

代码: 全选

● sed -e 's/([a-z])/\1 /g' <<< 'aabbccddeeffgg' | xargs -n1 | sort | uniq | wc -l
7
其他的,就这样吧。

代码: 全选

#!/bin/bash

while read line ; do
    line="${line%.com}"
    n="$(sed -re 's/(.)/\1 /g' <<< "$line" | xargs -n1 | sort | uniq -i | wc -l)"
    [ "$n" -lt 10 ]] && echo "${n} ${line}.com"
done < "${1}" | sort

代码: 全选

xxx.bash file 
执行。

代码: 全选

] ls -ld //
回复