ID 쌍과 더 높은 값과 더 낮은 값을 기반으로 파일을 구문 분석합니다.

ID 쌍과 더 높은 값과 더 낮은 값을 기반으로 파일을 구문 분석합니다.

File1에는 8개의 열이 있습니다. 열 3과 4는 rs|860 rs|756과 같은 쌍을 형성하며 이 쌍과 연관된 값은 열 8에 있습니다.

bb  yy  rs|860  rs|756  xx  aa  0.7 2234
bb  yy  rs|310  rs|260  xx  aa  0.3 9838
bb  yy  rs|110  rs|77   xx  aa  0.5 2291
bb  yy  rs|756  rs|860  xx  aa  0.4 2269
bb  yy  rs|110  rs|77   xx  aa  0.9 1112
bb  yy  rs|756  rs|860  xx  aa  0.8 3269
bb  yy  rs|233  rs|79   xx  aa  0.4 1397
bb  yy  rs|79   rs|233  xx  aa  0.7 1397

열 3과 4 또는 4와 3의 쌍은 동일하게 처리되어야 합니다(예: rs|860 rs|756 == rs|756 rs|860). 다음으로, 1행의 쌍이 4행과 6행에도 나타날 수 있습니다(또는 그 반대). 간단히 말해서 AB = BA = BA입니다. 먼저 col3과 col4를 행별로 정렬하여 AB = AB = AB와 같은 데이터를 만들고 싶습니다. 다음으로, 발생하는 모든 쌍 중에서 하나만 열 8의 최대값을 유지해야 합니다. 예를 들어 rs|860 rs|756은 행 6(즉, 3269)에 최대값이 있으므로 행 1과 4를 삭제해야 합니다. 마찬가지로 rs|110의 경우 rs|77 row5를 삭제해야 한다. 다음으로, 8열에 비슷한 값을 가진 쌍이 있다면, 7열에 더 높은 값을 가진 쌍을 유지해야 합니다. 예를 들어 rs|233 rs|79 row7인 경우 7열의 하위 값(0.4)을 삭제해야 합니다. 모든 쌍에 대해 열 8과 열 7 사이에 더 높은/낮은 차이가 없으면 둘 중 하나를 삭제할 수 있습니다.

원하는 출력 File2

bb  yy  rs|260  rs|310  xx  aa  0.3 9838
bb  yy  rs|77   rs|110  xx  aa  0.5 2291
bb  yy  rs|756  rs|860  xx  aa  0.8 3269
bb  yy  rs|79   rs|233  xx  aa  0.7 1397

답변1

이것은 우아하지 않은 awk솔루션입니다.

{
    split($3, a, "|")
    split($4, b, "|")
    if (a[2] > b[2]){
        $3=b[1]"|"b[2]
        $4=a[1]"|"a[2]
    }
    split(arr[$3" "$4], c, " ")
    if ($8 > c[8]){
        arr[$3" "$4] = $0
    }
}
END{
    for (item in arr){
        print(arr[item])
    }
}

다음으로 실행

awk -f script.awk input

간격을 유지하지 않으며 순서는 무작위입니다.

답변2

확립된pfnuesel의 답변,

{
    split($3, a, "|")
    split($4, b, "|")
    if (a[2] > b[2]){
        $3=b[1]"|"b[2]
        $4=a[1]"|"a[2]
    }
    key=$3" "$4
    split(arr[key], c, " ")
    if ($8 > c[8]  ||  ($8 == c[8] && $7 > c[7])){
        arr[key] = $0
    }
}
END{
    for (item in arr){
        print(arr[item])
    }
}

질문에 표시된 것처럼(명시적으로 언급되지는 않음) 세 번째 및 네 번째 열의 값이 다음과 같은 형식이라고 가정합니다.

some_string|숫자

공간은 설명 목적으로만 사용되며,문자가 포함되어 있지 않습니다 |. 이 태그는 다음을 기반으로 합니다.숫자s;이것접두사는 비교되지 않습니다.

에서와 같이pfnuesel의 답변, 사용법은

awk -f script.awk file1

입력 파일의 정확한 간격은 손실되지만 읽을 수 있는 열 간격은 파이핑을 통해 (재)생성될 수 있습니다 column -t.

awk -f script.awk file1 | column -t > file2

관련 정보