Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
319 views
in Technique[技术] by (71.8m points)

linux - Read an input number and redirect it to a column in a file

I have a file with a table like this:

Example input

I have done that my program returns me the values (max, min and mean) from the line of the gene that I'm looking for. Now my goal is the same, but instead of words, the user will print the number of the column. Ego to obtain these values but only from one column.

Here there is my code:

#!/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 ' ' '
' | cut -d' ' -f3- |  sort -n | head -1`
      max=` grep -m1 "$NAME" affy.txt  | tr -s '  ' ' ' |tr -s ',' '.' | cut -d ' ' -f3- | tr -s ' ' '
' | sort -n | tail -1`
      mean=` grep -m1 "$NAME" affy.txt | tr -s '  ' ' ' |tr -s ',' '.' | cut -d ' ' -f3- | tr -s ' ' '
' | 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

OPTION NUMBER 1 IS WORKING.

I tried something like this in the function named column, but it doesn't works...:

    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 ' ' '
' | 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
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Awk is a good tool for such column manipulation exercises; the following block shows how to get all the information on the column COL using 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;

Note that because we skip the header line, we calculate the average using sum/(NR-1) not sum/NR.

With your program it is important to be able to get the value of COL from the bash script. This can be done by using awk's -v parameter:

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

Put this together in a simplified columns function yields:

#!/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

This will print the information for one column in the file, which has a format as you described. From the code you posted it was unclear whether you wanted to be able to handle multiple columns in the same input; if so I'll leave it as an exercise for yourself.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...