This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
Beth, Last week, I mentioned in my decoders talk that one could slighty modify the metarWriter decoder to write the output to STDOUT. The code was commented to block the write to the station file and then to STDOUT. ie #open( STN, ">>$stn_name" ) ; #print STN "$_\n" ; #close STN ; print STDOUT "$_\n" ; A pqact entry would probably look similar to this: # All aviation reports including metar tests, broken/written to stn files DDS|IDS ^S(A....|P....|XUS8.) .... ([0-3][0-9]) PIPE /local/ldm/decoders/metarWriter (\2:yyyy)(\2:mm) | yourdecoder Robb... =============================================================================== Robb Kambic Unidata Program Center Software Engineer III Univ. Corp for Atmospheric Research address@hidden WWW: http://www.unidata.ucar.edu/ ===============================================================================
#! /usr/local/bin/perl # # metarWriter # # Program to split metar type bulletins into individual reports, then write # them to a directory structure ~/data/metar/yyyymmdd/stn using the station # name as the file name. The additional reports for the hour are appended to # file. # use Time::Local ; # process command line switches while ($_ = $ARGV[0], /^-/) { shift; last if /^--$/; /^(-v)/ && $verbose++; } # process input parameters if( $#ARGV == 0 ) { $yyyymm = $ARGV[ 0 ] ; die "yyyymm must be 6 in length: $!\n" if( length( $yyyymm ) != 6 ) ; $theyear = substr( $yyyymm, 0, 4 ) ; $themonth = substr( $yyyymm, 4 ) ; } else { die "usage: metarWriter yyyymm < rawMetars $!\n" ; } # set interrupt handler $SIG{ 'INT' } = 'atexit' ; $SIG{ 'KILL' } = 'atexit' ; $SIG{ 'TERM' } = 'atexit' ; $SIG{ 'QUIT' } = 'atexit' ; chdir( "$datadir" ) ; # Now begin parsing file and decoding observations breaking on cntrl C $/ = "\cC" ; # set select processing here from STDIN START: while( 1 ) { open( STDIN, '-' ) ; vec($rin,fileno(STDIN),1) = 1; $timeout = 1200 ; # 20 minutes $nfound = select( $rout = $rin, undef, undef, $timeout ); # timed out if( ! $nfound ) { print "Shut down, time out 20 minutes\n" ; atexit() ; } atexit( "eof" ) if( eof( STDIN ) ) ; # Process each line of metar bulletins, header first $_ = <STDIN> ; s#\cC## ; s#\cM##g ; s#\cA\n## ; s#\c^##g ; s#\d\d\d \n## ; s#\w{4}\d{1,2} \w{4} (\d{2})(\d{2})(\d{2}).*\n## ; $bday = $1 ; $bhour = $2 ; $bhour = "23" if( $bhour eq "24" ) ; $bmin = $3 ; next unless ( $bday && defined( $bhour ) && defined( $bmin ) ) ; next if( $bmin > 59 || $bhour > 23 || $bday > 31 ) ; # check for valid transmission times against current time $cday = (gmtime())[ 3 ] ; $chour = (gmtime())[ 2 ] ; # skip bulletins over 24 hours old or in the future if( $bday == $cday ) { next if( $bhour > $chour ) ; } else { # $bday != $cday, skip over day old reports next if( $bday < $cday -1 ) ; if( $bday > $cday ) { next if( $cday != 1 || $bday < 28) ; } next if( $bhour < $chour ) ; } if( s#(METAR|SPECI) \d{4,6}Z?\n## ) { $rep_type = $1 ; } elsif( s#(METAR|SPECI)\s*\n## ) { $rep_type = $1 ; } elsif( s#^MTR\w{3}\s*\n## ) { $rep_type = "METAR" ; } else { $rep_type = "METAR" ; } # Separate bulletins into reports if( /=\n/ ) { s#=\s+\n#=\n#g ; @reports = split( /=\n/ ) ; } else { @reports = split ( /\n/ ) ; } for ( @reports ) { # Process each report in the bulletin undef( $report ) ; undef( $remarks ) ; undef( $stn_name ) ; next if( /^\n|NIL/ ) ; s#^(METAR|M E T A R|SPECI|TESTM|TESTS)\s*\n?## ; if( /\n\w{4} \d{4,6}Z/ ) { # reports appended together wrongly ( $_, $tmp ) = split( "\n", $_ ) ; } s#\n# #g ; $rep_type = $1 if( s#^(METAR|SPECI|TESTM|TESTS)\s+## ) ; $stn_name = $1 if( m#^(\w{4})\s+# ) ; next unless( $stn_name ) ; # Valid time needed for dir structure if( m#(\d{2})(\d{2})(\d{2})Z# ) { $rday = $1 ; $rhour = $2 ; $rmin = $3 ; next unless ($rday && defined( $rhour ) && defined( $rmin )); next if( $rmin > 59 || $rhour > 23 || $rday > 31 ) ; # skip reports over 24 hours old if( $rday == $cday ) { next if( $rhour > $chour ) ; $tmpyyyymm = $yyyymm ; } else { # $rday != $cday, skip over day old reports next if( $rday < ( $cday -1 ) ) ; if( $rday > $cday ) { next if( $cday != 1 || $rday < 28) ; # cday = 1, reset month and year $tmpmonth = sprintf( "%02d", $themonth -1 ); if( $tmpmonth == 0 ) { $tmpmonth = "12" ; $tmpyear = sprintf( "%04d", $theyear -1 ); } else { $tmpyear = $theyear ; } $tmpyyyymm = $tmpyear . $tmpmonth ; } next if( $rhour < $chour ) ; } $yyyymmdd = $tmpyyyymm . $rday ; mkdir( "$yyyymmdd", 0775 ) if( ! -e "$yyyymmdd" ) ; chdir( "$yyyymmdd" ) ; } else { next ; } #open( STN, ">>$stn_name" ) ; #print STN "$_\n" ; #close STN ; print STDOUT "$_\n" ; chdir( ".." ) ; } # end foreach report } # end while( 1 ) atexit( "eof" ); exit( 0 ) ; #should never get here # execute at exit sub atexit { local( $sig ) = @_ ; if( $sig eq "eof" ) { print "eof on STDIN --shutting down\n" ; } elsif( defined( $sig )) { print "Caught SIG$sig --shutting down\n" ; } exit( 0 ) ; } #end atexit