다른 열에서 숫자가 발견될 때마다 변경되는 숫자나 문자열이 포함된 열을 어떻게 추가할 수 있나요?

다른 열에서 숫자가 발견될 때마다 변경되는 숫자나 문자열이 포함된 열을 어떻게 추가할 수 있나요?

다른 열(이 간단한 예에서는 세 개의 열)이 포함된 파일이 있습니다. 이러한 행에는 다양한 복제(Replicate_A, Replicate_B, Replicate_C)의 데이터가 포함됩니다. 그러나 매번 복사되는 행 수는 동일하지 않습니다(예: 3, 4, 5행). 내가 아는 유일한 것은 각 반복이 숫자 1로 시작한다는 것입니다. 이름이 중복된 추가 열을 추가하고 싶습니다. 이 열을 추가하는 방법에 대한 제안 사항이 있나요? 추가 열에 추가할 이름 목록이 포함된 추가 파일을 만들 수 있습니다. 어떤 조언이라도 도움이 될 것입니다.

내 파일은 탭으로 구분된 파일입니다.

1 x x  
2 x x  
3 x x  
4 x x  
1 x x  
2 x x  
3 x x  
1 x x  
2 x x  
3 x x

내가 원하는 파일

1 x x Replicate_A
2 x x Replicate_A
3 x x Replicate_A
4 x x Replicate_A
1 x x Replicate_B
2 x x Replicate_B
3 x x Replicate_B
1 x x Replicate_C
2 x x Replicate_C
3 x x Replicate_C

답변1

AWK를 사용하고 추가할 이름을 나열하는 별도의 파일을 사용하십시오.

#!/usr/bin/awk -f

BEGIN { FS = "\t"; OFS = FS; idx = 0 }
FNR == NR { names[NR] = $0 }
FNR < NR && $1 == 1 { idx++ }
FNR < NR { $(NF + 1) = names[idx]; print }

이는 탭을 입력 및 출력의 필드 구분 기호로 사용하도록 AWK를 설정합니다. 첫 번째 파일에는 추가할 이름이 포함되어 있다고 가정합니다. 이는 names배열로 읽혀집니다. 첫 번째 파일 이후의 파일로 이동하면 첫 번째 필드가 1인지 확인한 후 배열 인덱스를 증가시킨 후 줄 끝에 현재 이름을 추가합니다.

별도의 이름 목록은 없습니다.

#!/usr/bin/awk -f

BEGIN { FS = "\t"; OFS = FS; idx = 0 }
$1 == 1 { idx++ }
{ $(NF + 1) = sprintf("Replicate_%c", 64 + idx); print }

두 경우 모두 오류 처리가 없습니다. 첫 번째 변형에서는 이름이 모두 소모되면 빈 문자열이 사용됩니다. 2부에서는 Z 이후의 문자 세트를 탐색합니다.

답변2

문자 대신 숫자를 사용할 수 있다면 awk에서 쉽게 이 작업을 수행할 수 있습니다( file예제 데이터에 대한 실행 출력을 사용하여 sed -i 's/ */\t/g'데이터가 탭으로 구분되어 있으므로 모든 연속 공백을 탭으로 바꿉니다).

$ awk -F"\t" -vOFS="\t" '{if($1==1){num++}{print $0,"Replicate_"num}}' file 
1   x   x       Replicate_1
2   x   x       Replicate_1
3   x   x       Replicate_1
4   x   x       Replicate_1
1   x   x       Replicate_2
2   x   x       Replicate_2
3   x   x       Replicate_2
1   x   x       Replicate_3
2   x   x       Replicate_3
3   x   x   Replicate_3

문자가 필요한 경우 조금 더 복잡하지만 나쁘지는 않습니다.

$ awk '{
        if(NR==FNR){
            a[++n]=$1
        }
        else{
            if($1==1){
                num++
            }
            print $0,"Replicate_"a[num]
        }
       }' <(printf '%s\n' {A..Z}) file
1   x   x    Replicate_A
2   x   x    Replicate_A
3   x   x    Replicate_A
4   x   x    Replicate_A
1   x   x    Replicate_B
2   x   x    Replicate_B
3   x   x    Replicate_B
1   x   x    Replicate_C
2   x   x    Replicate_C
3   x   x Replicate_C

관련 정보