awk问题,一次在多个文件中重复行。

时间:2016-05-25 12:39:55

标签: linux bash awk duplicates printf

我在下面的格式化输出时遇到问题。

我在许多文件中重复了行SHORT_LIST.a SHORT_LIST.b SHORT_LIST.c,但可能有很多甚至更多。

“test1”行存在于所有三个文件中,字符串“sample”也是如此。

“test”行存在于两个文件中,但在其中一个文件中存在多次,我希望每个文件名只输出一次。

function check_duplicates {

 awk 'END {
   for (R in rec) {
   #split out the SHORT_LIST files
    n = split(rec[R], t, "/SHORT_LIST")
    #printf n dup[n]
    count = 0
if  ( n > 2 )
 dup[n] = dup[n] ? dup[n] RS sprintf( R, rec[R]) :
   sprintf("\t%-20s %s ", R, rec[R]);
}
for (D in dup) {
  ((count++))
   printf "%s\n \n", d
   printf count " ). Duplicate record(s) found in the following files: " dup[D]
     }
   }
{
   # build an array named rec (short for record), indexed by
   # the content of the current record ($0), concatenating
   # the filenames separated by / as values
   rec[$0] = rec[$0] ? rec[$0] "\n \t" FILENAME : FILENAME
   }' $SITEFILES

  }

check_duplicates

当前输出如下:

在以下文件中找到重复记录:

1)。在以下文件中找到重复的记录:test1
    SHORT_LIST.a     SHORT_LIST.b     SHORT_LIST.c 样品

2)。在以下文件中找到重复的记录:测试
    SHORT_LIST.c     SHORT_LIST.b     SHORT_LIST.b     SHORT_LIST.b

3)。在以下文件中找到重复的记录:/ path / to / file
    SHORT_LIST.a     SHORT_LIST.c 种皮

下面的所需输出:

在以下文件中找到重复记录:

1)。在以下文件中找到重复的记录:test1
    SHORT_LIST.a     SHORT_LIST.b     SHORT_LIST.c

2)。在以下文件中找到重复的记录:样本
    SHORT_LIST.a     SHORT_LIST.b     SHORT_LIST.c

3)。在以下文件中找到重复的记录:测试
    SHORT_LIST.c     SHORT_LIST.b

4)。在以下文件中找到重复的记录:/ path / to / file
    SHORT_LIST.a     SHORT_LIST.c

5)。在以下文件中找到重复的记录:testa     SHORT_LIST.a     SHORT_LIST.c

任何建议都会非常感激,我在这个级别的AWK上遇到了麻烦。

3 个答案:

答案 0 :(得分:2)

You can follow this template and fix the output format as desired

$ awk -f dups.awk fa fb fc

dups for : /path/to/file in files
fa fc
dups for : test in files
fa fb fc
dups for : sample in files
fa fb fc
no dups in
fc

$ cat dups.awk

  FNR==1{files[FILENAME]}
        {if((FILENAME, $0) in a) dupsInFile[FILENAME]
         else
           {a[FILENAME, $0]
            dups[$0] = $0 in dups ? (dups[$0] FS FILENAME) : FILENAME
            count[$0]++}}
     END{for(k in dups)
           {if(count[k] > 1)
              {print ("dups for : " k) " in files"
               print dups[k]}}
        for(f in dupsInFile) delete files[f];
        print "no dups in";
        for(f in files) printf "%s", f FS;
        printf "\n";
     }

,其中

$ head f{a,b,c}
==> fa <==
test
test
test1
sample
/path/to/file

==> fb <==
test
test
sample

==> fc <==
test
sample
/path/to/file

PS。始终提供样本输入。

答案 1 :(得分:1)

也许像

 awk '{print FILENAME "\t" $0}' $SITEFILES \
 | sort \
 | uniq -c -f1 \
 | awk "{if ($1 + .0 != 1) print $0}'

会让你入门

如果没有小样本数据集,就此做更多事情是不切实际的。

IHTH

答案 2 :(得分:0)

我将它拆分为多个文件,并且在同一个文件中,我也放入了内容以允许忽略注释,你也可以用空格来做,等等。

非常感谢@karakfa你的答案很棒,谢谢。

function check_duplicates {
 #Check multiple files for duplicates.   
  awk '
   FNR==1{files[FILENAME]}
          {if((FILENAME, $0) in a) dupsInFile[FILENAME]
           else
             {a[FILENAME, $0]
              dups[$0] = $0 in dups ? (dups[$0] RS FILENAME) : FILENAME
              count[$0]++}}
              #ignore comment lines
               {if ($0 ~ /#/) {
                   delete dups[$0]
                }}
  #Print duplicates in more than one file
          END{for(k in dups)
             {if(count[k] > 1)
               {print ("\n\n\tDuplicate line found: " k) "\n\tIn the following file(s)"
                 print dups[k] }}
          printf "\n";


       }' $SITEFILES
 #Check single files for duplicates.    
 awk '
 NR {
     b[$0]++
    }
    #ignore comment lines
        $0 in b {
           if ($0 ~ /#/) {
           delete b[$0]
                         }
                      if (b[$0]>1) {
                      print ("\n\n\tDuplicate line found: "$0) "\n\tIn the following file"
                      print FILENAME
                      delete b[$0]
                      }
    }' $SITEFILES


  }