如何在bash脚本数学运算中使用netcdf存储值?

时间:2014-04-08 11:52:26

标签: bash netcdf

我觉得这可能是相当容易做的事情,我用Google搜索并搜索了这里的问题,但我找不到它。也许这是因为我没有问正确的问题。

我想从netcdf文件中获取变量的数值,并在我的bash脚本中的数学运算中使用它。我试过了:

 a=5*"./myfile.nc"
 a=5*./myfile.nc
 echo $a

在两种情况下我都会得到:

 ./myfile.nc: Permission denied
 1*/home/cohara/RainfallData/rainfall_increase/5%over10years.nc

ncdump将文件中包含的所有信息打印到终端,但如何选择我想要的变量,以便在脚本中使用?

这是ncdump输出。这是我要提取的var61的值:

{
    dimensions:
    lon = 1 ;
    lat = 1 ;
    height = 1 ;
    time = UNLIMITED ; // (1 currently)
variables:
    double lon(lon) ;
        lon:standard_name = "longitude" ;
        lon:long_name = "longitude" ;
        lon:units = "degrees_east" ;
        lon:axis = "X" ;
    double lat(lat) ;
        lat:standard_name = "latitude" ;
        lat:long_name = "latitude" ;
        lat:units = "degrees_north" ;
        lat:axis = "Y" ;
    double height(height) ;
        height:standard_name = "height" ;
        height:long_name = "height" ;
        height:units = "m" ;
        height:positive = "up" ;
        height:axis = "Z" ;
    double time(time) ;
        time:standard_name = "time" ;
        time:units = "year as %Y.%f" ;
        time:calendar = "proleptic_gregorian" ;
    float var61(time, height, lat, lon) ;
        var61:table = 1 ;
        var61:_FillValue = -9.e+33f ;

// global attributes:
        :CDI = "Climate Data Interface version 1.5.5 (http://code.zmaw.de/projects/cdi)" ;
        :Conventions = "CF-1.0" ;
        :history = "Tue Apr 08 12:40:41 2014: cdo divc,10 /home/cohara/RainfallData/rainfall_increase/historical_5%.nc /home/cohara/RainfallData/rainfall_increase/5%in10parts.nc\n",
            "Tue Apr 08 12:40:41 2014: cdo mulc,5 /home/cohara/RainfallData/rainfall_increase/historical_1%.nc /home/cohara/RainfallData/rainfall_increase/historical_5%.nc\n",
            "Tue Apr 08 12:40:41 2014: cdo divc,100 /home/cohara/RainfallData/rainfall_increase/historical_mean.nc /home/cohara/RainfallData/rainfall_increase/historical_1%.nc\n",
            "Tue Apr 08 12:40:41 2014: cdo timmean /home/cohara/RainfallData/rainfall_increase/historical.nc /home/cohara/RainfallData/rainfall_increase/historical_mean.nc\n",
            "Fri Mar 21 10:16:32 2014: cdo splityear ./1981-2076.nc ./1981-2076_\n",
            "Tue Mar 04 14:18:04 2014: cdo settaxis,1981-01-01,00:00:00,1year ./RainfallData/timsum_1981.nc ./RainfallData/settaxis.nc\n",
            "Tue Mar 04 13:55:00 2014: cdo timsum /home/cohara/RainfallData/fldmean_1981.nc /home/cohara/RainfallData/timsum_1981.nc\n",
            "Tue Mar 04 13:45:48 2014: cdo fldmean /home/cohara/RainfallData/corrected_precip_1981.nc /home/cohara/RainfallData/fldmean_1981.nc\n",
            "Tue Mar 04 13:43:26 2014: cdo divc,10 /home/cohara/RainfallData/PRECIP_1981.nc /home/cohara/RainfallData/corrected_precip_1981.nc\n",
            "Mon Jul 15 13:16:49 2013: cdo cat WD2_1981m10grid.csv.nc WD2_1981m11grid.csv.nc WD2_1981m12grid.csv.nc WD2_1981m1grid.csv.nc WD2_1981m2grid.csv.nc WD2_1981m3grid.csv.nc WD2_1981m4grid.csv.nc WD2_1981m5grid.csv.nc WD2_1981m6grid.csv.nc WD2_1981m7grid.csv.nc WD2_1981m8grid.csv.nc WD2_1981m9grid.csv.nc PRECIP_1981.nc\n",
            "Fri Jul 12 09:11:31 2013: cdo -f nc copy WD2_1981m10grid.csv.grb WD2_1981m10grid.csv.nc" ;
        :CDO = "Climate Data Operators version 1.5.5 (http://code.zmaw.de/projects/cdo)" ;
data:

 lon = 0 ;

 lat = 0 ;

 height = 0 ;

 time = 2012 ;

 var61 =
  5.293939 ;
}

提前感谢您的帮助。

席亚拉

2 个答案:

答案 0 :(得分:0)

试试这个:

a=$(ncdump myfile.nc | grep "var61:_FillValue" | sed -e "s/.*= //;s/ .*//")

说明:

  • 管道将一个程序的输出发送到另一个程序的输入。
  • grep删除与给定字符串不匹配的每一行
  • sed做了一些正则表达式魔术,它有两个部分用";"
    • 第一部分匹配" ="并取而代之的
    • 第二部分匹配" "并取而代之的

我目前没有正确的netcdf文件进行测试,但使用ncdump -v var61 myfile.nc的内容可能会更容易。

修改的 如果您希望答案为5.293939,请使用

a=$(ncdump myfile.nc |sed -z -e "s/.* var61 =\n  //;s/ .*//")

我想我在上面搜索了错误的值。

替代:

a=$(ncdump myfile.nc |awk '/var61 =/ {nextline=NR+1}{if(NR==nextline){print $1}}')

它的工作原理如下:

  • 语句1:
    • /var61 =/搜索斜杠之间的字符串
    • NR包含行号。 nextline设置为下一行号
  • 语句2
    • 当NR等于下一行时,则
    • 打印行中的第一个单词

答案 1 :(得分:0)

我通常在ncdump上使用-v选项,以防文件非常大,因为它更快。

这应该获取变量的值:

myvar=`ncdump -v,var61 tm.nc | tail -n 2 | head -n 1 | awk '{print $1;}'`

我只是使用头部和尾部来切断netcdf文件头并结束,因为我发现它更容易理解和记住!

请注意,这只适用于具有单个值的变量(在您的问题和示例文件中似乎就是这种情况),因为tail命令正在拾取最后两行。如果要获取变量数组的第一个条目,则需要进行修改。