LoginSignup
0
1

More than 5 years have passed since last update.

bash > 可変列の3ファイルを合成して、各行に3項目ずつ出力する実装 > 遅い実装と速い実装 > pasteでのワンライナーを教えていただきました

Last updated at Posted at 2017-03-15
動作環境
Xeon E5-2620 v4 (8コア) x 2
32GB RAM
CentOS 6.8 (64bit)
openmpi-1.8.x86_64 とその-devel
mpich.x86_64 3.1-5.el6とその-devel
gcc version 4.4.7 (とgfortran)
NCAR Command Language Version 6.3.0
WRF v3.7.1を使用。

以下の3つのファイルを一対一対応にしたい。
データの個数は65 * 82。

  • out_val_170315 : 対象とする値のファイル
  • out_lat_170315 : 緯度
  • out_lon_170315 : 経度
$ head out_* | less
==> out_lat_170315 <==
  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  36.07  
    36.07  36.07 
  36.19  36.19  36.19  36.19  36.19  36.19  36.19  36.19  36.19  36.19  

==> out_lon_170315 <==
  131.17  131.29  131.41  131.53  131.65  131.77  131.89  132.01  132.13  
    132.25  132.37  132.49  132.61  132.73  132.85  132.97  133.09  133.21  
    133.33  133.45  133.57  133.69  133.81  133.93  134.05  134.17  134.29  
    134.41  134.53  134.65  134.77  134.89  135.01  135.13  135.25  135.37  
    135.49  135.61  135.73  135.85  135.97  136.09  136.21  136.33  136.45  
    136.57  136.69  136.81  136.93  137.05  137.17  137.29  137.41  137.53  
    137.65  137.77  137.89  138.01  138.13  138.25  138.37  138.49  138.61  
    138.73  138.85  138.97  139.09  139.21  139.33  139.45  139.57  139.69  
    139.81  139.93  140.05  140.17  140.29  140.41  140.53  140.65  140.77  
    140.89 

==> out_val_170315 <==

   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00
   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00   0.00

v0.1 code > 遅い (3分以上)

combine_3files_170315_exec
#!/usr/bin/env bash

set $(cat $1 | tr '\n' ' ') $(cat $2 | tr '\n' ' ') $(cat $3 | tr '\n' ' ')

size=$(expr 65 \* 82)

for loop in $(seq 1 $size)
do
  pos2=$(expr $loop + $size)
  pos3=$(expr $loop + $size \* 2)
  optpos="$loop,$pos2,$pos3"

  echo $@ | cut -d ' ' -f $optpos
done
実行例
$ bash combine_3files_170315_exec out_val_170315 out_lat_170315 out_lon_170315 
0.00 36.07 131.17
0.00 36.07 131.29
0.00 36.07 131.41
0.00 36.07 131.53
0.00 36.07 131.65
0.00 36.07 131.77
0.00 36.07 131.89
0.00 36.07 132.01
0.00 36.07 132.13
0.00 36.07 132.25
0.00 36.07 132.37
0.00 36.07 132.49
0.00 36.07 132.61
(後略)

4000行処理するのに3分27秒かかる。
遅い。

v0.2 code > 0.5秒

ちょっと変更してみた。

参考 http://stackoverflow.com/questions/17403498/iterate-over-two-arrays-simultaneously-in-bash

combine_3files_170315_exec
#!/usr/bin/env bash

array1=( $(cat $1 | tr '\n' ' ') )
array2=( $(cat $2 | tr '\n' ' ') )
array3=( $(cat $3 | tr '\n' ' ') )
for ((i=0;i<${#array1[@]};++i)); do
    printf "%s %s %s\n" "${array1[i]}" "${array2[i]}" "${array3[i]}"
done

5330行処理に0.5秒になった。

教えていただいた事項

@kitsuyui さんのコメントにてpasteを用いたワンライナーを教えていただきました。

情報感謝です。

0
1
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1