using ncap to modify a variable in SHELL

Paul S.
  • Paul S.

    Paul S. - 2014-05-06

    Hi Dr. Zender and NCOers,

    I tried to modify a character variable in a bunch of netcdf files. One of them is like:
    char Times(Time, DateStrLen) ;
    Time = UNLIMITED ; // (1 currently)
    DateStrLen = 19 ;
    Times =
    "1991-01-01_00:00:00" ;

    ncap2 -s 'Times(:,0:3)=("2091")'
    ncdump, I got
    Times =
    "2091-01-01_00:00:00" ;

    But when I tried this in SHELL, e.g.,
    ncap2 -s "Times(:,0:3)=("${yearfuture}")"
    I also tried
    ncap2 -s "Times(:,0:3)="${yearfuture}""
    also tried
    ncap2 -s "Times(:,0:3)=${yearfuture}"

    ncdump, then I got:
    Times =
    "++++-01-01_00:00:00" ;

    Could you please help on this? Thanks!

  • Charlie Zender

    Charlie Zender - 2014-05-07

    Hello Paul,

    Getting this to work from the shell is challenging.
    As far as I can tell it show ncap2 needs a new function that
    converts numbers to formatted strings without saving those
    strings as variables in the file, e.g., int2string(1999)="1999".
    Unfortunately this functionality may be hard to implement.
    I hope Henry chimes in on this possibility.

    For a shorter term workaround, try something like this.
    Here date_rec is a record array of date strings (like yours).
    The record length is 10 and the length of the year is four,
    so ncap2 needs 40 characters to do what you want:

    ncap2 -O -v -s "date_rec(:,0:3)=\"$year\"" ~/nco/data/ ~/

    In other words the shell variable needs to have the correct
    number of characters (that part can also be scripted).
    Then protect the quotes ncap2 sees with backslashes and you're set.


  • Charlie Zender

    Charlie Zender - 2014-05-07

    zender@roulee:~$ ncks -H -C -v date_rec ~/nco/data/
    time[0]=1 char_dmn_lng26[0] date_rec[0--25]='2010-11-01T00:00:00.000000'
    time[1]=2 char_dmn_lng26[0] date_rec[26--51]='2010-11-01T01:00:00.000000'
    time[2]=3 char_dmn_lng26[0] date_rec[52--77]='2010-11-01T02:00:00.000000'
    time[3]=4 char_dmn_lng26[0] date_rec[78--103]='2010-11-01T03:00:00.000000'
    time[4]=5 char_dmn_lng26[0] date_rec[104--129]='2010-11-01T04:00:00.000000'
    time[5]=6 char_dmn_lng26[0] date_rec[130--155]='2010-11-01T05:00:00.000000'
    time[6]=7 char_dmn_lng26[0] date_rec[156--181]='2010-11-01T06:00:00.000000'
    time[7]=8 char_dmn_lng26[0] date_rec[182--207]='2010-11-01T07:00:00.000000'
    time[8]=9 char_dmn_lng26[0] date_rec[208--233]='2010-11-01T08:00:00.000000'
    time[9]=10 char_dmn_lng26[0] date_rec[234--259]='2010-11-01T09:00:00.000000'

    zender@roulee:~$ year=1999199919991999199919991999199919991999
    zender@roulee:~$ ncap2 -O -v -s "date_rec(:,0:3)=\"$year\"" ~/nco/data/ ~/
    zender@roulee:~$ ncks -H -C -v date_rec ~/
    time[0]=1 char_dmn_lng26[0] date_rec[0--25]='1999-11-01T00:00:00.000000'
    time[1]=2 char_dmn_lng26[0] date_rec[26--51]='1999-11-01T01:00:00.000000'
    time[2]=3 char_dmn_lng26[0] date_rec[52--77]='1999-11-01T02:00:00.000000'
    time[3]=4 char_dmn_lng26[0] date_rec[78--103]='1999-11-01T03:00:00.000000'
    time[4]=5 char_dmn_lng26[0] date_rec[104--129]='1999-11-01T04:00:00.000000'
    time[5]=6 char_dmn_lng26[0] date_rec[130--155]='1999-11-01T05:00:00.000000'
    time[6]=7 char_dmn_lng26[0] date_rec[156--181]='1999-11-01T06:00:00.000000'
    time[7]=8 char_dmn_lng26[0] date_rec[182--207]='1999-11-01T07:00:00.000000'
    time[8]=9 char_dmn_lng26[0] date_rec[208--233]='1999-11-01T08:00:00.000000'
    time[9]=10 char_dmn_lng26[0] date_rec[234--259]='1999-11-01T09:00:00.000000'

  • Paul S.

    Paul S. - 2014-05-07

    Hi Charlie,

    Thanks for the tips. This dirty trick works for my tests.

    When the length of record is 1, by changing parenthesis to backslash, it works.

    (1) ncap2 -s "Times(:,0:3)=("${yearfuture}")"
    Times =
    "++++-01-01_00:00:00" ;
    (2) ncap2 -s "Times(:,0:3)=\"${yearfuture}"\"
    Times =
    "2091-01-01_00:00:00" ;

    (3) ncap2 -s "Times(:,0:3)=\"${yearfuture}\""
    it (3) also yields the same result as (2)

    Thanks for your replies!

  • Charlie Zender

    Charlie Zender - 2014-05-07

    Henry, is there a better way to do this? e.g., is int2string() function above workable? would need to circumvent creating temporary dimensions... or could print() somehow be modified to work, e.g.,
    ncap2 -O -v -s "date_rec(:,0:3)=print($year,%4d)" ~/nco/data/ ~/

  • henry Butowsky

    henry Butowsky - 2014-05-08

    Hi Charlie -
    will try and write a str2long function this weekend - It will return a character attribute ?

  • Charlie Zender

    Charlie Zender - 2014-05-08

    we need something like

    char * long2str(long foo,char *format);

    that takes a number foo and a C-format string and returns a string that can be
    used internally by ncap2 any place a string is needed, e.g., the above situation where a string of length 4 was needed for the year. Thanks!


Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:

No, thanks