특정 용어가 포함된 행의 열 합계

특정 용어가 포함된 행의 열 합계

동일한 식별자를 가진 모든 행 열을 합산하는 sed명령 이 있는지 알고 싶습니다 . awk예를 들어 내 파일은 data.txt아래와 같지만 약 1800개의 데이터 열과 약 1400개의 행을 포함합니다.

ABCD:1234  1.23  0.23  0.83   0
ABCD:1234    0    1.10  0.21   0 
EFGH:5678    0    1.90  0.12  8.21
IJKL:9999    1.22  0    1.84  9.21
IJKL:9999    1.44  0   12.94   0
IJKL:9999    1.32  0   24.12   2.43

나중에 명령이 어떻게 보이길 원하는지 :

ABCD:1234  1.23  1.33  1.04  0
EFGH:5678    0    1.90  0.12  8.21
IJKL:9999   3.98   0   38.9  11.64

awk이것이 또는 sed(저는 생물학자이고 여전히 Unix의 기본을 배우고 있습니다) 과 함께 작동하는지 잘 모르겠습니다 . 어떤 도움이라도 대단히 감사하겠습니다.

답변1

awk입력 파일이나 전체 결과 테이블을 메모리에 보관하지 않는 스크립트:

FNR == 1   { for(i = 1; i <= NF; i++) a[i] = $i;  next }
$1 == a[1] { for(i = 2; i <= NF; i++) a[i] += $i; next }
{
    printf "%s", a[1]; a[1] = $1;
    for(i = 2; i <= NF; i++) { printf "\t%s", a[i]; a[i] = $i };
    printf "\n";
}
END {
    printf "%s", a[1];
    for(i = 2; i <= NF; i++) printf "\t%s", a[i];
    printf "\n";
}

실행하세요:

awk -f script.awk data.txt

결과:

ABCD:1234       1.23    1.33    1.04    0
EFGH:5678       0       1.90    0.12    8.21
IJKL:9999       3.98    0       38.9    11.64

참고 사항: 실제로는 작동 sed하지만 곧 그렇게 하지는 않을 것입니다. 바라보다여기이유를 알아보세요.

답변2

대체 솔루션perl

$ perl -nale '
if(!$seen{$F[0]}++)
{
    print join "\t", @a if @a;
    @a = @F[0..$#F];
}
else
{
    $a[$_] += $F[$_] foreach(1..$#F);
}
print join "\t", @a if eof;
' data.txt 
ABCD:1234   1.23    1.33    1.04    0
EFGH:5678   0       1.90    0.12    8.21
IJKL:9999   3.98    0       38.9    11.64
  • -a입력 줄을 공백으로 분할하고 @F배열 에 저장합니다.
  • 행의 첫 번째 필드는 해시 변수의 키로 사용됩니다 %seen. 키를 찾을 수 없으면 @a배열의 내용이 인쇄되고(비어 있지 않은 경우) 새 행의 필드가 배열에 할당됩니다.
  • 키가 이미 존재하는 경우 배열의 내용(두 번째 필드부터 끝까지)을 현재 행의 해당 내용에 추가합니다.
  • @a마지막 항목을 처리하려면 파일 끝에 도달하면 배열 내용을 다시 인쇄하십시오.


중복 질문의 경우:첫 번째 열에 동일한 항목이 있으면 Linux에서 모든 열을 별도로 추가하십시오.

$ perl -nale '
if(!$seen{$F[0]}++)
{
    print join "\t", @a if @a;
    @a = @F[0..$#F];
}
else
{
    $a[$_] += $F[$_] foreach(1..$#F);
}
print join "\t", @a if eof;
' filename.txt 
AC1481523   6   6   6   6
AC1481676   6   5   6   8


배열 해시를 구축하고 마지막에 해시를 인쇄하는 솔루션:

$ perl -nale '
if($h{$F[0]})
{
    $h{$F[0]}[$_] += $F[$_] foreach (1..$#F)
}
else
{
    $h{$F[0]} = [@F]
}
END { print join "\t",@{$h{$_}} foreach sort keys %h }
' data.txt
ABCD:1234   1.23    1.33    1.04    0
EFGH:5678   0       1.90    0.12    8.21
IJKL:9999   3.98    0       38.9    11.64

관련 정보