동일한 식별자를 가진 모든 행 열을 합산하는 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