다른 두 열의 고유한 조합을 기반으로 열에서 그룹을 가져오는 방법

다른 두 열의 고유한 조합을 기반으로 열에서 그룹을 가져오는 방법

다음과 같은 데이터가 있습니다.

Sample_1    Apples  Red
Sample_2    Apples  Red
Sample_3    Apples  Red
Sample_4    Apples  Red
Sample_5    Apples  Red
Sample_6    Apples  Green
Sample_7    Apples  Green
Sample_8    Apples  Green
Sample_9    Apples  Green
Sample_10   Apples  Green
Sample_11   Apples  Yellow
Sample_12   Apples  Yellow
Sample_13   Apples  Yellow
Sample_14   Apples  Yellow
Sample_15   Apples  Yellow

다른 두 열에서 형성된 그룹의 조합을 기반으로 첫 번째 열에서 샘플을 반복적으로 가져와 샘플 1-5, 6-10 및 11-15를 얻으려면 어떻게 해야 합니까?

내가 궁극적으로 원하는 것은 샘플 목록(위의 그룹)을 다른 명령의 입력으로 가져오는 것입니다. 예:

comm -23 <(sort <all_samples.txt>) <(sort <[input from above]>) > <difference.txt>

나는 시도했다:

awk '{print $2"\t"$3}' <file.txt> | uniq

두 번째와 세 번째 열의 고유한 조합을 얻으려면 이 작업을 수행할 수 없는 것 같습니다. 특히 첫 번째 열을 가져오는 것이 필요합니다.

답변1

이것이 당신이하려는 일입니까?

$ awk '{vals[$2 FS $3] = vals[$2 FS $3] OFS $1} END{for (key in vals) print key vals[key]}' file
Apples Red Sample_1 Sample_2 Sample_3 Sample_4 Sample_5
Apples Green Sample_6 Sample_7 Sample_8 Sample_9 Sample_10
Apples Yellow Sample_11 Sample_12 Sample_13 Sample_14 Sample_15

아니면 이거?

$ awk -v fruit='Apples' -v color='Green' '($2==fruit) && ($3==color)' file
Sample_6    Apples  Green
Sample_7    Apples  Green
Sample_8    Apples  Green
Sample_9    Apples  Green
Sample_10   Apples  Green

답변2

이것은 입력을 구문 분석하고 필요에 적합해 보이는 데이터의 전치를 출력하는 gawk 스크립트의 간단한 예입니다.

#!/usr/bin/gawk -f

# Checks if type (column 2) or subtype (column 3) are 
# different from previous line.
(type != $2) || (subtype != $3) {
    # Prints the start of a new output line.
    # The NR!=1 check avoids that a new line is 
    # printed on the first line.
    printf("%s%s\t%s\t", (NR!=1)?"\n":"", $2, $3);
    type=$2;
    subtype=$3
}
{
    # Prints all sample (column 1) values on the 
    # current output line.
    printf("\"%s\" ", $1);
}
# prints a new line at the end of file.
END{
    print "";
}

다음 의 출력 script.awk < input.lst. script.awk이전 스크립트는 어디에 있고 input.lst입력 예제는 어디에 있습니까?

Apples  Red     "Sample_1" "Sample_2" "Sample_3" "Sample_4" "Sample_5" 
Apples  Green   "Sample_6" "Sample_7" "Sample_8" "Sample_9" "Sample_10" 
Apples  Yellow  "Sample_11" "Sample_12" "Sample_13" "Sample_14" "Sample_15" 

스크립트 출력은 다음과 같이 쉽게 조작할 수 있습니다.

script.awk < input.lst | while read TYPE SUBTYPE LIST
do 
    echo $TYPE
    echo $SUBTYPE
    for ITEM in $LIST
    do  
        echo execute some command on $ITEM where type is $TYPE and subtype is $SUBTYPE
    done 
done

이 스크립트는 매우 거칠다는 점에 유의하세요. 예를 들어 오류 처리가 없으며 입력에 공백이나 특수 문자가 있는지 확인하지 않습니다.

답변3

아래 스크립트를 사용해 보았고 정상적으로 작동했습니다.

for i in "Apples"; do for j in "Red" "Green" "Yellow"; do awk -v i="$i" -v j="$j" 'BEGIN{print "Below are table contains" " " i " and " " " j}$2==i && $NF==j{print $0}' filename; done; done

산출

Below are table contains Apples and  Red
Sample_1    Apples  Red
Sample_2    Apples  Red
Sample_3    Apples  Red
Sample_4    Apples  Red
Sample_5    Apples  Red
Below are table contains Apples and  Green
Sample_6    Apples  Green
Sample_7    Apples  Green
Sample_8    Apples  Green
Sample_9    Apples  Green
Sample_10   Apples  Green
Below are table contains Apples and  Yellow
Sample_11   Apples  Yellow
Sample_12   Apples  Yellow
Sample_13   Apples  Yellow
Sample_14   Apples  Yellow
Sample_15   Apples  Yellow

관련 정보