Добавление имени файла к подсчитанным данным - PullRequest
0 голосов
/ 17 декабря 2018

Предположим, у меня есть файлы, подобные следующим.

файл 1

1,144931087,144931087,T,C  
16,89017167,89017167,C,G  
17,7330235,7330235,G,T  
17,10222478,10222478,C,T  

файл 2

1,144931087,144931087,T,C
16,89017167,89017167,C,G
17,10222478,10222478,C,T

файл 3

17,10222478,10222478,C,T  

Я хотел бы выяснить, сколько раз дублированные значения присутствуют в каждом файле, поэтому в идеале вывод будет выглядеть так:

Вывод

2 1,144931087,144931087,T,C  
2 16,89017167,89017167,C,G  
3 17,10222478,10222478,C,T  
1 17,7330235,7330235,G,T 

Я использовал следующую команду для подсчета значения дубликатов.

sort Test1.csv Test2.csv Test3.csv | uniq --count

Теперь я хочу добавить имя файла для подсчитанного вывода.Мой желаемый результат должен выглядеть следующим образом:

Test1 Test2 2 1,144931087,144931087,T,C  
Test1 Test2 2 16,89017167,89017167,C,G  
Test1 Test2 Test 3 3 17,10222478,10222478,C,T  
Test1 1 17,7330235,7330235,G,T  

Может кто-нибудь помочь мне получить желаемый результат или кто-нибудь может предложить мне лучший способ получить желаемый результат?

Ответы [ 4 ]

0 голосов
/ 17 декабря 2018

Еще один ответ с использованием Perl.

> cat file1m.csv
1,144931087,144931087,T,C
16,89017167,89017167,C,G
17,7330235,7330235,G,T
17,10222478,10222478,C,T
> cat file2m.csv 
1,144931087,144931087,T,C
16,89017167,89017167,C,G
17,10222478,10222478,C,T
> cat file3m.csv
17,10222478,10222478,C,T
> cat uniq_perl.ksh
perl -lne ' 
@t=@{ $kvf{$_} };
if( not $ARGV ~~ @t ) { push(@t,$ARGV); $kvf{$_}=[ @t ] ;  }
close(ARGV) if eof; 
END { for(keys %kvf) { @x=@{$kvf{$_}};  print join(" ",@x)." ".scalar(@x)." ".$_  } }   
' file*m*csv 
> ./uniq_perl.ksh
file1m.csv file2m.csv file3m.csv 3 17,10222478,10222478,C,T
file1m.csv 1 17,7330235,7330235,G,T
file1m.csv file2m.csv 2 1,144931087,144931087,T,C
file1m.csv file2m.csv 2 16,89017167,89017167,C,G
> 
0 голосов
/ 17 декабря 2018

Ввод:

more Test*.csv
::::::::::::::
Test1.csv
::::::::::::::
1,144931087,144931087,T,C
16,89017167,89017167,C,G
17,7330235,7330235,G,T
17,10222478,10222478,C,T
::::::::::::::
Test2.csv
::::::::::::::
1,144931087,144931087,T,C
16,89017167,89017167,C,G
17,10222478,10222478,C,T
::::::::::::::
Test3.csv
::::::::::::::
17,10222478,10222478,C,T

Команда:

awk '{tmp[$0]++;if(length(tmp2[$0])==0){tmp2[$0]=FILENAME;next}tmp2[$0]=tmp2[$0] OFS FILENAME}END{for(elem in tmp){print tmp2[elem] OFS tmp[elem] OFS elem}}' Test*.csv

Вывод:

Test1.csv Test2.csv 2 1,144931087,144931087,T,C
Test1.csv Test2.csv 2 16,89017167,89017167,C,G
Test1.csv Test2.csv Test3.csv 3 17,10222478,10222478,C,T
Test1.csv 1 17,7330235,7330235,G,T

Пояснения:

  # gawk profile, created Mon Dec 17 14:46:47 2018

  # Rule(s)

   {
           tmp[$0]++ #associative array to count the occurrences freq
           if (length(tmp2[$0]) == 0) {  #when you add the first occurrence filename you do not need to add a space
                   tmp2[$0] = FILENAME
                   next
            }
           #append to variable with a space
           tmp2[$0] = tmp2[$0] OFS FILENAME
    }

    # END rule(s)

    END {
           # loop on each element of the associative arrays and print them
           for (elem in tmp) {
                   print tmp2[elem] OFS tmp[elem] OFS elem
            }
    }

if...next... можно заменить на (length(tmp2[$0]) == 0 ? tmp2[$0] = FILENAME : tmp2[$0] = tmp2[$0] OFS FILENAME), чтобы упростить сценарий awk:

  {
       tmp[$0]++
       (length(tmp2[$0]) == 0 ? tmp2[$0] = FILENAME : tmp2[$0] = tmp2[$0] OFS FILENAME)
  }

  END {
         for (elem in tmp) {
              print tmp2[elem] OFS tmp[elem] OFS elem
         }
  }
0 голосов
/ 17 декабря 2018

Не могли бы вы попытаться выполнить следующее, и это должно дать вам вывод в строку ввода Input_file.Я использовал gsub(/[[:space:]]+$/,""), так как ваши Input_file (s) имеют пробелы в последних строках, поэтому, удалив их здесь, вы можете удалить их, если это НЕ тот случай.

awk '
{
  gsub(/[[:space:]]+$/,"")
}
!a[$0]++{
  b[++count]=$0
}
{
  c[$0]++
  d[$0]=d[$0]?d[$0] OFS FILENAME:FILENAME
}
END{
  for(i=1;i<=count;i++){
    print d[b[i]]"|"c[b[i]],b[i]
  }
}'  test1 test2 test3

Вывод будет следующим.

test1 test2|2 1,144931087,144931087,T,C
test1 test2|2 16,89017167,89017167,C,G
test1|1 17,7330235,7330235,G,T
test1 test2 test3|3 17,10222478,10222478,C,T
0 голосов
/ 17 декабря 2018

Использование awk.Извините за мою умную схему именования файлов:

$ awk '{
    a[$0]++                   # count hits
    b[$0]=b[$0] FILENAME " "  # store filenames
}
END {
    for(i in a)               
        print b[i] a[i],i     # output them
}' foo bar baz
foo bar 2 1,144931087,144931087,T,C
foo bar 2 16,89017167,89017167,C,G
foo bar baz 3 17,10222478,10222478,C,T
foo 1 17,7330235,7330235,G,T

ОБНОВЛЕНО за комментарии:

$ awk 'BEGIN {
    FS=OFS=","
} 
{
    a[$1 OFS $2 OFS $3 OFS $4]++ 
    b[$1 OFS $2 OFS $3 OFS $4]=b[$1 OFS $2 OFS $3 OFS $4] FILENAME "|"
    c[$1 OFS $2 OFS $3 OFS $4]=$0                      # keep the last record with 
}                                                      # specific key combination 
END { 
    for(i in a) 
        print b[i] "," a[i],c[i]  
}' foo  bar baz
foo|bar|,2,16,89017167,89017167,C
foo|,1,17,7330235,7330235,G
foo|bar|,2,1,144931087,144931087,T
foo|bar|baz|,3,17,10222478,10222478,C
...