CU论坛的一个问题...刚好正在学习脚本,折腾了一下,OK,记录一下.

问题:

两文件第一列相同,需要得到每一行除第一列外相同的数的个数,如

 
  
  1. ~$ cat kkk
  2. 1 2 3 
  3. 2 9 8 3 
  4. 3 6 7 8 5 
  5. 4 3 5 1 
  6. 5 8 
 
  
  1. cat ddd
  2. 1 3 2 
  3. 2 8 9 1 
  4. 3 6 8 9 5 
  5. 4 3 2 
  6. 5 9 2 

希望得到的结果

 
  
  1. $ cat sort.txt 
  2. 1       2 
  3. 2       2 
  4. 3       3 
  5. 4       1 
  6. 5       0 

结果中第一列为文件第一列,第二列为两文件每一列重复的个数,如结果中第一行第二列的2 由于d.txt第一行与e.txt第一行,除第一列外有两个数是重复的,而得到的

脚本:

 
  
 
  
  1. #!/bin/bash 
  2. PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin 
  3. export PATH 
  4.  
  5. Var_file1=`mktemp /tmp/tmp.XXXXXXX` 
  6. Var_file2=`mktemp /tmp/tmp.XXXXXXX` 
  7. Var_id=`mktemp /tmp/tmp.XXXXXXX` 
  8. Var_sort=`mktemp /tmp/tmp.XXXXXX` 
  9.  
  10. cut -d ' ' -f 2- $1 > $Var_file1 
  11. cut -d ' ' -f 2- $2 > $Var_file2 
  12. cut -d ' ' -f 1 $2 > $Var_id 
  13.  
  14. while read -u 3 Var_a; read -u 5 Var_b 
  15. do 
  16.     echo ${Var_a} ${Var_b} | sed 's: :\n:g' | sort | uniq -d |wc -l >> $Var_sort 
  17. done 3<$Var_file1 5<$Var_file2 
  18. paste $Var_id $Var_sort>sort.txt 
  19. rm -f $Var_file1 $Var_file2 $Var_id $Var_sort 


这个脚本用到了文件描述符,同时对两文件实现读取...记录一下...

如果用awk有更简单的办法,其它兄弟的

 
  
  1. awk 'NR==FNR{for(i=2;i<=NF;i++){a[FNR","i]=$i;b[FNR]=NF}}NR>FNR{n=0;for(i=2;i<=NF;i++)for(j=1;j<=b[FNR];j++)if($i==a[FNR","j])n++;print $1,n}' kkk ddd

 
  
awk还没熟悉到这个地步...学习中....  还有管道命令,其它兄弟的 
 
  
  1. while read line; do echo "${line%% *} $(echo "${line#* }" | tr ' ' '\n' | sort | uniq -d | wc -l)"; done < <(join ddd kkk) 
read 命令参考: -p 用 |& (管道,& 的记号名称)读取由 Korn shell 运行的进程的输出作为输入。 注:-p 标志的文件结束符引起该进程的清除,因此产生另外一个进程。 -r 指定读取命令把一个 \ (反斜杠) 处理为输入行的一部分,而不把它作为一个控制字符。 -s 把输入作为一个命令保存在 Korn shell 的历史记录文件中。 -u [ n ] 读取一位数的文件描述符号码 n 作为输入。文件描述符可以用 ksh exec 内置命令打开。n 的缺省值是 0,表示的是键盘。值 2 表示标准错误。