总结群里提问的shell问题

a文件
22924 183.136.221.76 200
  20747 119.146.204.15 200
  19563 61.182.133.37 200
  19150 112.85.218.29 200
  18002 113.106.128.3 200
  123 113.106.128.3 200


b文件
113.106.128.3
1.1.1.1
61.182.133.37

各位,怎么样将a文件 $2等于b文件的$1 的记录全部打印出来


awk 'FNR==NR{a[$0]}NR>FNR{if($2 in a)print}' b a


当然了还有高人这么回答的:

grep -F -f b a

具体含义请使用man grep

但是有人第一次这么回答了:
awk '{a[$2]=$2}NR>FNR{if(a[$1]++)print}' a b
这条语句的意思是找出a和b存在的相同的部分******************************************************************************************************************************python问题:0123456789ABCDEF,在python中如何每两个切成一组答案:
echo 0123456789ABCDEF|sed -r 's/../&,/g;s/^(.*),$/\[\1\]/' [01,23,45,67,89,AB,CD,EF]
[s[i:i+2] for i in range(0, len(s), 2)]
['01', '23', '45', '67', '89', 'AB', 'CD', 'EF']
a=[0123456789ABCDEF]
i=0
while a :
i+=2
a[0],a[1]
a=a[i:]
re.subn(r'(..)', '\\1,', s)[0].split(',')[:-1]
['01', '23', '45', '67', '89', 'AB', 'CD', 'EF']******************************************************************************************************************************
需求:找出文件中的所有中文并删除重复的汉字(ps:因为想到汉化recovery的中文太大了,有个想法是把需要的中文全部集中起来然后只使用用到的中文生成字库,这样生辰的recovery就会小很多,定制性很强)代码:
awk '/[^\u4E00-\u9FA5]/{FS=""
    $0=$0
    for(i=1;i<length($0);i++)
    {
        if($i ~ /[^\u4E00-\u9FA5]/ && $i !~ /[][ a-zA-Z(),.*:"!/{}&%+=;#<>_|?\\^$,-]/ && $i !~ /'"'"'/) 
            cn=cn$i
    }
}
END{
    $0=cn
    FS=""
    for(i=1;i<length($0);i++)
    {
        res=$i"\n"res
    }
    print res
}' $* | sort | uniq | tr -d "\n"

分析:这里有一点需要注意,使用/[^\u4E00-\u9FA5]/虽然可以匹配到所有的中文,但是无法排除我在里面列出的_等字符,还有a-zA-Z也包含了不清楚什么情况。。。

只能使用枚举法把所有不想要的字符再排除掉,还有一个注意事项就是单引号,因为awk 使用了单引号作为命令的一部分,那么就有必要使用双引号把单引号引起来

最后重新给$0赋值遍历单个字符添加换行进而使用sort 配合uniq去除重复字符,最后把换行删除,

自我感觉这个脚本写的有点复杂,应该还有更简单的做法,由于对正则了解不是很深刻,暂时写了这么个解法,欢迎修正,指点


******************************************************************************************************************************

出个题目:数据如下
1,2,3,a,b
fa,1
cc,1,3
af
以逗号为分隔符将文件中将域的从多到小重新打印到文件
1,2,3,a,b
cc,1,3
fa,1
af
按NF排序,打印到文件域相同的不作要求


方案1:

awk -F',' '{a[NF] = a[NF] ? a[NF] ORS $0 : $0; max = max < NF ? NF : max}END{for(i=max; i>0; --i)if(a[i])print a[i]}' urfile
方案2:

cat a.txt  |awk -F',' '{print $0,NF}'|sort -rn -k2 

方案3:python版本

#!/usr/bin/env python

file=open(r'./a')
line=file.readlines()

res=[]
dict={}
for i in line:
    lengh=len(i.split(';'))
    if not lengh in res:
        res.append(lengh)
        dict[lengh]=i
    else:
        dict[lengh]=dict[lengh]+i

res.sort()
for i in res:
    print dict[i],

方案4:另外一个python版

#!/usr/bin/env python
set,dict=[],{}
 for str in open("a.txt"):                         
    num =  len(str.split(',') 
    if not num in dict:
           dict [num] = str
    else:
          dict [num] +=str+'\n'
set = sort(dict.keys())
for item in set: print(dict[item])
(PS:这里使用了srot,但是我在windows的python2.7版本里发现没有sort这个函数,只能使用sorted,于是我改写了最后两条语句为:

for item in sorted(D):
    print dict[item]

******************************************************************************************************************************
现在有两个文件file_1和file_2
#cat file_1
[section_A]
a=2
b=3
[section_B]
a=4
d=5


#cat file_2


[section_A]
a=1
b=1
c=1
[section_B]
a=2
b=2
c=2
d=2
用file_1中的同区域的值来替换file_2中同区域的值,结果应该如下:
#cat file_2
[section_A]
a=2
b=3
c=1
[section_B]
a=4
b=2
c=2

d=5 


awk -F'=' -vOFS="=" 'NR==FNR{if(/^\[/){gsub(/\[|\]/,"",$0);x=$0;next};a[x","$1]=$2;next}{if(/^\[/){y=$0};for(i in a){split(i,k,",");if(y~k[1]){if($1==k[2]){$2=a[i]}}}}1'  file_1 file_2

****************************************************************************************************************

需求:

20001
21001
22001
23001
24001
25001
26001
27001
28001
29001
30001
31001
32001
33001
34001
35001
36001
37001
38001
39001
前10行第一个数字改为5,后10行第一个数字改为6

答案:

awk '{$0=(NR<=10?"5":"6")substr($0,2,length($0)-1)}1' 1
就这个题意单纯的来说,也可以用awk '{$0=substr($0,1,1)+3substr($0,2,length($0)-1)}1'
其实就是第一位+3
更简单的就是整个数字+30000
awk '{print $0+30000}'
需求增加...:

20001 21000 1_1000.log
21001 22000 21001_22000.log
22001 23000 22001_23000.log
23001 24000 23001_24000.log
24001 25000 24001_25000.log
25001 26000 25001_26000.log
26001 27000 26001_27000.log
27001 28000 27001_28000.log
28001 29000 28001_29000.log
29001 30000 29001_30000.log
30001 31000 30001_31000.log
31001 32000 31001_32000.log
32001 33000 32001_33000.log
33001 34000 33001_34000.log
34001 35000 34001_35000.log
35001 36000 35001_36000.log
36001 37000 36001_37000.log
37001 38000 37001_38000.log
38001 39000 38001_39000.log
39001 40000 39001_40000.log 其实我要做的是比这个多。 前10行第一个数字2改成3, 第三列log文件的名字要是前面2列的数字组合。 后10行以此第一个数字3递增到4
第1,2列只改第一个数字,第3列是前面2列数字的组合

答案:

awk '{$1=$1+10000;$2=$2+10000;$3=$1"_"$2".log"}1' 1
对1的解释:同理,awk ‘{print}’完整的写法也是awk ‘1{print}’。
完整写法应该是1{print $0} 

kidd兄弟出的问题:

 1. 用shell找出/www/www.xunlei.com 下最后修改时间是最近2个月大于600K扩展名为.jpg的文件,并删除。 

find /www/www.xunlei.com -mtime -60 -name "*.jpg"  -size +60k -exec rm -f {} \;
我来钻个牛角尖,如果文件末尾含有空格的话,上述有问题

find /www/www.xunlei.com -mtime -60 -name "*.jpg"  -size +60k -print0 | xargs -0 rm -f 
2. 考试题四:用shell建一个用户组xunlei,建立用户user0-user30 且属组是xunlei
groupadd xunlie;for i in `seq 0 30`;do useradd user$i -g xunlie;done
3. 考试题五:用shell在/usr/local下 建立20个子目录 xunlei1-xunlei20,再在这20个子目录下分别建255个子目录dir1-dir255,再在255个子目录下创建10000个文件 xunlei1.html-xunlei10000.html
mkdir -p /usr/local/xunlei{1..20}/dir{1..225};touch  /usr/local/xunlei{1..20}/dir1..25/xunlei{1..10000}.html
4. 考试题十:一个文件ett.log,共20行内容,请切割为每五行一个新文件
split -l 5 ett.log


问题:根据文本file1的内容格式化输出

file1:内容如下:

Num	ID	Type
274     1001    1
143     1001    2
134     1001    3
47      1002    1
26      1002    2
13      1002    3
15      1003    3
输出格式如下:第一列输出ID,第二列-第四列依次输出Type1,2,3对应的Num

1001	274	143	134
1002	47	26	13
1003			15
答案:命令如下:

awk '{if(!a[$2]++)b[++n]=$2;c[$2,$3]=$1}END{for(i=1;i<=n;i++){for(j=1;j<=3;j++)s=s?s"\t"c[b[i],j]:b[i]"\t"c[b[i],j];print s;s=""}}' file1
解释:
!a[$2]++ 用来判断ID第一次出现的,例如1001第一次出现的时候a[$2]的结果是0 然后取! 得到1 即True然后使用数组b[++n]把ID保存起来, 使用数组c[$2,$3]保存Num,

**************************************************************************************************************************

需求:匹配数组里面一个元素,需要返回对应的下标 

a=(1 2 3)
for i in ${!a[@]}; do echo $i; done
解释说明:这里出现了一个比较特殊的字符 "!" 在这里的含义就是取得数组的下标






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值