awkで最大値

a 11
b 43
c 89
d 62
e 35

こんなデータがhoge.txtとしてあるとき、最大値やら平均やらを出力するコマンドはすぐに見つかったが、最大値を取るアルファベットを出力する場合に少し手こずったので書いておく。

まずは最大値を出力する場合。
$ cat hoge.txt | awk ‘{if(m<$2) m=$2 } END{print m}' 次に、アルファベットを出力する場合。 $ cat hoge.txt | awk '{if(m<$2) {m=$2; n=$1} } END{print n}' 要するにif文の後の実行文が二つになるので、中括弧を一つ増やせばよかっただけでした。

データ解析(bash&gnuplot)

磁場を振って測った電流のデータを、素子の劣化を考慮して直線補正するためのスクリプト。

まずは、カンマをスペースに置換し、200行毎に空行を2行挟む(gnuplotのindexでデータを分けるため)。

直線によるフィッティングの結果からデータを補正するのだが、
普通に$1、$2とやろうとするとbashの変数と混同するため、
あらかじめ$1を文字列と解釈してくれる変数aを定義しておく。
最後に、補正したデータをテーブルにダンプして終わり。

#!/bin/bash

if [ $# -ne 1 ]; then
  echo "please add the filename!"
  exit 1
fi

tail -701 $1 | sed -e 's/,/   /g' | sed -e '201~200i \\n' > test.txt

a=\$1
b=\$2

gnuplot -e "
  f(x)=a*x+b ; g(x)=c*x+d; h(x)=e*x+f;
  a=1;b=1;c=1;d=1;e=1;f=1;
  fit f(x) 'test.txt' i 0 u 1:2 via a,b;
  fit g(x) 'test.txt' i 1 u 1:2 via c,d;
  fit h(x) 'test.txt' i 2 u 1:2 via e,f;
  unset key;
  set xlabel 'Magnet Voltage (V)';
  set ylabel 'Current (A)';
  plot 'test.txt' i 0 u 1:($b-$a*a) w l, '' i 1 u 1:($b-$a*c) w l, '' i 2 u 1:($b-$a*e) w l;
  pause -1 ;
  set table 'test.table';
  replot;
  "

sed

ある条件に一致する行を見つけたら、その下の固定行数を抜き出したい場合。
sedを使うとそれなりに簡単にできることがわかった。
例は,i= 7を含む行と、加えて241行を抜き出す。

sed -n -e "/ i =    7/,+241p" pos.xyz >> pos-7.xyz

最後の行を削除する。

sed -i -e '$d' foo.txt

-i オプションはファイルを上書きする命令。

ファイルの行数の読み込み

事前にファイルの行数を取得したい場合。
巨大なファイルを誤って読み込もうとしてしまった場合、スタックしてしまいそうではある。

nlines=File.read("filename").count("\n")

現在何行目かを知りたい場合はこちら。

f = open(ARGV[0], "r")
while a = f.gets
  puts f.lineno
end

メソッド []=

ベクトルの要素を上書きするようなメソッドを作成したものの、'[]=’メソッドがないと言われて怒られるので、作成してみる。これで、直観的な取扱いが可能に。

class Vector
   def []=(i, x)
      @elements[i]=x
   end
end