匹配列值而不查看订单

匹配列值而不查看订单

我试图比较两列的值而不看它的顺序。我尝试对值求和并在匹配时匹配它们,然后将“匹配”,否则“不匹配”放在附加列中。但这里的问题是,两个数的和可以相同,例如:

虚拟的想法(我认为这可能会发生,因为列表很长):

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我们就去掉了标题行,现在我们只有五个空格分隔的文件。字段 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

相关内容