0

我有一个像这样的表的文件:

示例输入

我已经完成了我的程序从我正在寻找的基因行中返回值(最大值、最小值和平均值)。现在我的目标是相同的,但用户将打印列号而不是单词。自我获得这些值,但只能从一列。

这是我的代码:

#!/bin/bash

FICHERO="affy.txt"

function OPTIONS
{
   echo "_____________OPTIONS_____________"
   echo ""
   echo "   1. Select one gene and its test results"
   echo "  2. Select one column and its test results"
   echo "               3. Exit"
}

function gene
{
   if [ -e "affy.txt" ]; then  # Si el fichero existe...
      echo "Print the name of the gene you are looking for: "
      read -p "Name:" NAME
      OLDIFS=$IFS
      IFS=","; 
      # Calcular max, min y mean.
      min=` grep -m1 "$NAME" affy.txt |tr -s ',' '.' | tr -s ' ' '\n' | cut -d' ' -f3- |  sort -n | head -1`
      max=` grep -m1 "$NAME" affy.txt  | tr -s '  ' ' ' |tr -s ',' '.' | cut -d ' ' -f3- | tr -s ' ' '\n' | sort -n | tail -1`
      mean=` grep -m1 "$NAME" affy.txt | tr -s '  ' ' ' |tr -s ',' '.' | cut -d ' ' -f3- | tr -s ' ' '\n' | awk '{sum+=$1} END {print sum/NR}'`

      echo "Min value: "$min
      echo "Max value: "$max
      echo "Mean value: "$mean


   else
      echo "Invalid gene name!"
   fi

   echo
}

function column
{   
   if [ -e $FICHERO ]; then
      echo "Print the column number you are looking for: "
      read -p "Name: " NAME


   else
      echo "El fichero no existe o no contiene entradas en la agenda"
   fi
}

opc=0
exit=5

while [ $opc -ne $exit ];
do   
   clear
   OPTIONS  # Dibujamos el menu en pantalla
   read -p "Opcion:..." opc  # Escogemos la opcion deseada

   if [ $opc -ge 1 ] && [ $opc -le 5 ]; then
      clear
      case $opc in   # Acciones para las diferentes opciones del menu

         1)gene   
            ;;

         2)column
            ;;
      esac
  else
  echo "Insert a correct option!!"

  fi
  echo "Press any key..."
  read
  done

选项 1 有效。

我在名为 column 的函数中尝试了类似的方法,但它不起作用......:

    function column
{   
   if [ -s $FICHERO ]; then
      echo "Print the column number you are looking for: "
      read -p "column: " column
      for i in "$column"
      do
         col+="${i#-}"","
         echo "You are working with column number:" $col
      done

   else
      echo "El fichero no existe o no contiene entradas en la agenda"
   fi

   if [ "$col" = "" ]; then
          echo "Insert Columns please!"
   else
      for i in $col; 
      do 
      echo
      echo minim columna= `tr -s ',' '.' affy.txt | tr -s ' ' '\n' | cut -d' ' -f"$col" |  sort -n | head -1`
      echo maxim columna "$i"= `grep "$col" affy.txt | tr -s '  ' ' ' |tr -s ',' '.' | cut -d ' ' -f"$i" | sort -n | tail -1`
      echo average columna "$i"= `grep "$col" affy.txt | tr -s '  ' ' ' |tr -s ',' '.' | cut -d ' ' -f"$i" | awk '{sum+=$0} END {print sum/NR}'`

      shift
      done
   fi
4

2 回答 2

0

有一个更简单的方法。忘记整个程序,只关注手头的问题。您通常如何获得要打印的列?给定你的文件。

GENE  RESULT1 RESULT2 RESULT3
GENE1    1       6       9
GENE2    2       6       7
GENE3    2       4       9
GENE4    1       6       9

目标:通过位置编号(1、2、3 等)获取 RESULT 值。输入:一个正整数 >= 1,但 <= 3 {x| 1 <= x <= 3} 输出:一列数字。

隐含的事实:第 1 列 ($1) 用于标签,返回的列不应包含标题信息。这使得以下成为真正的竞争环境:

1       6       9
2       6       7
2       4       9
1       6       9

解决方案:

用户输入。

  1. 程序的第一部分应该可以使用数字 1。现在,$1 将引用 GENE 标签列。因此,当输入任何值时,将其加 1,以便您始终获得您真正想要的列。因此,零和负数不是用户可接受的回复。此外,总共只有三个列在起作用。因此,数字 3 是您的程序应该处理的最大数字(现在)。

  2. 您应该考虑的第二件事是使用将打印第一行之外的所有行的命令。head 和 tail 命令有很多选项。

    尾-n 4

这是收成...

GENE1    1       6       9
GENE2    2       6       7
GENE3    2       4       9
GENE4    1       6       9

因此,当上面的 a 命令通过管道传送到 awk

read $REPLY  (2)  *<----User inputs 2*

REPLY=$(($REPLY + 1))

tail -n 4 | awk "{print $REPLY}"       (where $REPLY really = 3)

6
6
4
6

繁荣!打印第二列。我认为您可能更喜欢将此解决方案集成到您的程序中,而不是此处列出的其他解决方案。

于 2014-05-28T18:46:19.140 回答
0

awk 是进行此类列操作练习的好工具;以下块显示如何COL使用 awk 获取列上的所有信息:

  awk 'BEGIN{min=999;sum=0} # Set initial values
  { if(NR <= 1){ next }     # Skip first line which is the column name
    if ($COL<min){min=$COL} # Store minimum so far
    if($COL>max){max=$COL}  # Store maximum so far
    sum+=$COL; }            # Store sum of the column
    END { print "minim columna="min;
        print "maxim columna="max;
        print "average columna="sum/(NR-1);}' file.txt;

请注意,因为我们跳过了标题行,所以我们使用sum/(NR-1)not计算平均值sum/NR

对于您的程序,重要的是能够COLbash脚本中获取 的值。这可以通过使用 awk 的-v参数来完成:

awk -v "COL=$col" 'BEGIN{ ...

把它放在一个简化的columns函数中产生:

#!/bin/bash

FICHERO="affy.txt"

function column
{   
    if [ -s $FICHERO ]; then
      echo "Print the column number you are looking for: "
      read -p "column: " column
      col="${column#-}"
      echo "You are working with column number:" $col
    else
      echo "El fichero no existe o no contiene entradas en la agenda"
    fi

    if [ "$col" = "" ]; then
      echo "Insert Columns please!"
    else
      echo
      let col+=1 # Add 1 to column name as we assume that 1 will be the first column of data
      awk -v "COL=$col" 'BEGIN{min=999;sum=0}
      { if(NR <= 1){ next }     # Skip first line which is the column name
        if ($COL<min){min=$COL} # Store minimum so far
        if ($COL>max){max=$COL}  # Store maximum so far
        sum+=$COL; }            # Store sum of the column
        END { print "minim columna="min;
              print "maxim columna="max;
          print "average columna="sum/(NR-1);}' $FICHERO;
     fi
}

column

这将打印文件中一列的信息,其格式如您所述。从您发布的代码中,不清楚您是否希望能够在同一输入中处理多个列;如果是这样,我会把它留给自己练习。

于 2013-10-27T03:42:02.593 回答