순서를 보지 않고 열 값 일치

순서를 보지 않고 열 값 일치

순서를 보지 않고 두 열의 값을 비교하려고 합니다. 값을 합산하고 일치하면 일치시킨 다음 추가 열에 "일치", 그렇지 않으면 "일치하지 않음"을 넣어 보았습니다. 그러나 여기서 문제는 두 숫자의 합이 동일할 수 있다는 것입니다. 예를 들면 다음과 같습니다.

더미 아이디어(목록이 꽤 길기 때문에 이런 일이 발생할 수 있다고 생각합니다):

7+5=12;  5+7=12 = Match
6+6=12;  4+8=12 = Nomatch in theory while seeing the numbers but summing them showing the Match.

    locus   truth   predicted
CSF1PO_007-BC03_20171027_2149   11,12   11,12
CSF1PO_007-BC04_20171027_2149   11,12   11,12
CSF1PO_19_20171027_2149 10,12   12,10
CSF1PO_20_20171027_2149 10,0    10,11
CSF1PO_A-10_2018123_1836    12,0    12,13
CSF1PO_A-11_2018123_1836    10,12   12,10
CSF1PO_A-1_20181222_0036    10,11   10,11
CSF1PO_A-12_2018123_1836    11,12   11,12
CSF1PO_A-13_2018123_1836    8,10    10,8
CSF1PO_A-14_2018123_1836    8,11    8,11

지금까지 합계 및 일치를 사용해 보았습니다.

cat test | sed '1d' | sed 's/,/\t/g' | awk '{print $1"\t"$2+$3"\t"$4+$5}' | awk '{ if ($2 == $3) print $1"\t"$2"\t"$3"\t""Match"; else print  $1"\t"$2"\t"$3"\t""NoMatch"}'

Output:
CSF1PO_007-BC03_20171027_2149   23  23  Match
CSF1PO_007-BC04_20171027_2149   23  23  Match
CSF1PO_19_20171027_2149 22  22  Match
CSF1PO_20_20171027_2149 10  21  NoMatch
CSF1PO_A-10_2018123_1836    12  25  NoMatch
CSF1PO_A-11_2018123_1836    22  22  Match
CSF1PO_A-1_20181222_0036    21  21  Match
CSF1PO_A-12_2018123_1836    23  23  Match
CSF1PO_A-13_2018123_1836    18  18  Match
CSF1PO_A-14_2018123_1836    19  19  Match

참고: 또한 기억해야 할 한 가지는 다른 열의 값과 일치하는 숫자는 "일치"로 간주될 수 있다는 것입니다.

Example:
CSF1PO_20_20171027_2149 10,0    10,11 === Match as one number matches (order does not matter)
CSF1PO_A-10_2018123_1836    12,0    12,13 === Match as one number matches (order does not matter)

내가 시도한 한 가지 가능한 솔루션은 작동하는 것 같지만 설명이나 다른 가능한 솔루션이 필요합니다.

cat test | sed '1d' | sed 's/,/\t/g' | awk '{ if ($2 == $4 || $2 == $5) print $0 , "=>", "Match"; else if ($3 == $5 || $3 == $4) print $0 , "=>", "Match"; else print $0,"=>","Nomatch"}'

CSF1PO_007-BC03_20171027_2149   11  12  11  12 => Match
CSF1PO_007-BC04_20171027_2149   11  12  11  12 => Match
CSF1PO_19_20171027_2149 10  12  12  10 => Match
CSF1PO_20_20171027_2149 10  0   10  11 => Match
CSF1PO_A-10_2018123_1836    12  0   12  13 => Match
CSF1PO_A-11_2018123_1836    10  12  12  10 => Match
CSF1PO_A-1_20181222_0036    10  11  10  11 => Match
CSF1PO_A-12_2018123_1836    11  12  11  12 => Match
CSF1PO_A-13_2018123_1836    8   10  10  8 => Match
CSF1PO_A-14_2018123_1836    8   11  8   11 => Match

내가 이 일을 제대로 하고 있는지 설명이 필요합니다. 감사해요

답변1

내 생각에 당신의 줄 구조는 다음과 같습니다. 첫 번째 공백 앞에 임의의 텍스트가 있는 줄입니다. 그런 다음 공백으로 구분된 두 개의 필드가 있습니다. 각 필드는 쉼표로 구분된 두 개의 숫자로 구성됩니다. 또한 첫 번째 공백 앞의 텍스트에는 쉼표가 없는 것 같습니다.

파이프라인의 첫 번째 부분은 좋아 보입니다. 따라서 실행 후 위의 가설이 맞다면 cat test | sed '1d' | sed 's/,/\t/g' > test2헤더 행을 제거하고 이제 공백으로 구분된 파일은 5개만 남게 됩니다. 필드 2와 3은 첫 번째 숫자 쌍이고, 필드 4와 5는 두 번째 숫자 쌍입니다.

귀하의 질문은 분명하기 때문에 이것은 다시 제 부분에 대한 약간의 추측입니다. 필드 2와 3 중 하나 또는 둘 다 일치하려면 필드 4와 5 중 하나 또는 둘 다와 같아야 합니다. 그 중 어떤 일치 항목이 있는지는 중요하지 않습니다(일치해야 하는 순서쌍으로 간주되지 않음).

따라서 두 개가 아닌 하나의 awk 조각만 사용할 수 있습니다.

awk '($2==$4 || $2==$5 || $3==$4 || $3==$5) { print $0 " Match" }' < test2

하나의 awk 스크립트에서 이 모든 작업을 수행할 수도 있습니다. 공백과 쉼표를 사용하여 필드를 구분하고 첫 번째 줄을 무시하도록 awk에 지시할 수 있기 때문입니다.

# -F changes the input field seperator
awk -F '[[:space:],]' '
  # remove the first line
  NR==1 {next}
  # execute block if any of these field combinations match
  ($2==$4 || $2==$5 || $3==$4 || $3==$5) { print $0 " Match" }
  # reverse the condition and print stuff for not matching lines
  ($2!=$4 && $2!=$5 && $3!=$4 && $3!=$5) { print $0 " Nomatch" }
' < test

답변2

답변해 주셔서 감사합니다. 하지만 파일 목록이 길고 그 중 일부는 "불일치"이기 때문에 "불일치"도 원합니다.

D18S51_A-13_2018123_1836    14  16  13.2    9 => Nomatch
D18S51_A-16_2018123_1836    13  16  13.2    9 => Nomatch
D18S51_A-9_20181222_0036    13  15  9   13.2  => Nomatch
D18S51_NISTB1_ps109_75ng    13  16  9   13.2  => Nomatch
D18S51_str10or15_BC04       13  14  13.2   18 => Nomatch
D21S11_NISTB1_ps109_75      32  32.2  33   33 => Nomatch
D5S818_str10or15_BC01       11  12  13  10    => Nomatch
FGA_str10or15_BC05          19  22  26  23    => Nomatch
vWA_A-18_2018123_1836       18  0   21  19    => Nomatch

관련 정보