比较文件的连续列并获取匹配元素的数量

时间:2015-05-30 18:33:56

标签: bash shell awk

我想比较文件的连续列并返回匹配元素的数量。我更喜欢使用shell脚本或awk。以下是我尝试使用的示例bash / AWK脚本。

#!/bin/bash
for i in 3 4 5 6 7 8 9 

do

  for j in 3 4 5 6 7 8 9

     do
  `awk "$i == $j" phased.txt | wc -l`

     done
done

我有一个大小为147189 * 828的文件,我想比较每一列并返回828 * 828矩阵中的匹配元素数(A相似矩阵)。 这在MATLAB中相当容易,但是,加载大文件需要很长时间。我可以比较两列并使用以下awk命令返回匹配元素的数量:

awk '$3==$4' phased.txt | wc -l

但需要一些帮助来完成整个文件。

我正在处理的数据片段是:

# sampleID  HGDP00511  HGDP00511   HGDP00512   HGDP00512   HGDP00513  HGDP00513   

M rs4124251       0       0            A            G          0          A

M rs6650104       0       A            C            T          0          0

M rs12184279      0       0            G            A          T          0

................................................................................

在比较之后,我将在这种情况下计算一个6 * 6矩阵:包含这些列的匹配百分比。

1 个答案:

答案 0 :(得分:0)

在bash中,变量需要$进行解释,因此您的awk "$i == $j" phased.txt | wc -l将被评估为awk "3 == 4" phased.txt | wc -l;然后,由于你的反引号(`),shell将尝试将其作为命令执行。要获取awk以查看$3 == $4,您需要添加\$awk "\$$i == \$$j" phased.txt | wc -l

#!/bin/bash
for i in 3 4 5 6 7 8 9     
do
  for j in 3 4 5 6 7 8 9
  do
    awk "\$$i == \$$j" phased.txt | wc -l
  done
done

虽然您可能想要展示您正在评估的组合:

#!/bin/bash
for i in 3 4 5 6 7 8 9     
do
  for j in 3 4 5 6 7 8 9
  do
    echo "$i $j: $(awk "\$$i == \$$j" phased.txt | wc -l)"
  done
done

你实际上可以直接在awk中进行计数

#!/bin/bash
for i in 3 4 5 6 7 8 9     
do
  for j in 3 4 5 6 7 8 9
  do
    echo "$i $j: $(awk "\$$i == \$$j {count++}; END{print count}" phased.txt)"
  done
done

最后,你可以用awk完成整个事情;它几乎肯定会更快,但说实话它并不那么干净:[未测试]

#!/usr/bin/env awk -f

{
    for (i = 3; i <= 9; i++) {
        for (j = 3; j <= 9; j++) {
            if ($i == $j) {
                counts[i, j]++
            }
        }
    }
}

END {
    for (i = 3; i <= 9; i++) {
        for (j = 3; j <= 9; j++) {
            printf "%d = %d: %d\n", i, j, counts[i, j]
        }
    }
}