program column ! !******************************************************************************* ! !! COLUMN extracts a given column from a file. ! ! ! Note: ! ! The file is presumed to consist of lines of data. ! Each line of data contains several words, separated by one or more ! spaces or TAB characters. ! The first "word" in each line is the first "column", and so on. ! ! Example: ! ! The input file contains: ! ! 1 2 3 4 5 ! 18 19 20 21 22 ! 1440 778 9909 2333 0999 ! ! The command: ! ! column 3 input_file output_file ! ! will create an output file containing column 3: ! ! 3 ! 20 ! 9909 ! ! Calling sequence: ! ! column ICOLNUM FILEIN FILEOUT ! ! Modified: ! ! 26 August 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Integer COLNUM, is the column number to be extracted. ! ! Character ( len = 80 ) FILEIN, is the input file to be read. ! ! Character ( len = 80 ) FILEOUT, is the output file to which the extracted ! data should be written. If FILEOUT is omitted, then the ! data is written to the terminal. ! implicit none ! integer colnum logical, parameter :: debug = .false. character ( len = 80 ) filein character ( len = 80 ) fileout integer iarg integer iargc integer ierror integer ilen integer input_unit integer ios integer ipxfargc integer lenc character ( len = 256 ) line integer nmiss integer numarg integer nword integer output_unit character ( len = 80 ) word ! if ( debug ) then call timestamp ( ) write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'COLUMN' write ( *, '(a)' ) ' Extract a column of data from a file.' end if ierror = 0 nmiss = 0 ! ! Old style: ! numarg = iargc ( ) ! ! New style: ! ! numarg = ipxfargc ( ) ! ! Get the column number. ! if ( numarg < 1 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'Enter the column number to be extracted.' read ( *, * ) colnum else iarg = 1 ! ! Old style: ! call getarg ( iarg, word ) ! ! New style: ! ! call pxfgetarg ( iarg, word, ilen, ierror ) ! ! if ( ierror /= 0 ) then ! write ( *, '(a)' ) ' ' ! write ( *, '(a)' ) 'COLUMN - Error!' ! write ( *, '(a)' ) ' Could not read the argument.' ! stop ! end if call s_to_i ( word, colnum, ierror, lenc ) if ( ierror /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'COLUMN - Error!' write ( *, '(a)' ) ' The column number is not an integer.' stop end if end if if ( colnum <= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'COLUMN - Error!' write ( *, '(a)' ) ' The column number must be positive.' stop end if ! ! Get the input filename. ! if ( numarg < 2 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'Enter the input filename.' read ( *, '(a)' ) filein else iarg = 2 ! ! Old style: ! call getarg ( iarg, filein ) ! ! New style: ! ! call pxfgetarg ( iarg, filein, ilen, ierror ) ! ! if ( ierror /= 0 ) then ! write ( *, '(a)' ) ' ' ! write ( *, '(a)' ) 'COLUMN - Error!' ! write ( *, '(a)' ) ' Could not read the argument.' ! stop ! end if end if ! ! Get the output filename. ! if ( numarg >= 3 ) then iarg = 3 ! ! Old style: ! call getarg ( iarg, fileout ) ! ! New style: ! ! call pxfgetarg ( iarg, fileout, ilen, ierror ) ! ! if ( ierror /= 0 ) then ! write ( *, '(a)' ) ' ' ! write ( *, '(a)' ) 'COLUMN - Error!' ! write ( *, '(a)' ) ' Could not read the argument.' ! stop ! end if end if ! ! Open the input file. ! call get_unit ( input_unit ) open ( unit = input_unit, file = filein, status = 'old', iostat = ios ) if ( ios /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'COLUMN - Fatal error!' write ( *, '(a)' ) ' Could not open the input file:' // trim ( filein ) stop end if ! ! Open the output file. ! if ( numarg >= 3 ) then call get_unit ( output_unit ) open ( unit = output_unit, file = fileout, status = 'replace', & iostat = ios ) if ( ios /= 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'COLUMN - Fatal error!' write ( *, '(a)' ) ' Could not open the output file: ' // trim ( fileout ) close ( unit = input_unit ) stop end if end if ! ! Read a line of input, extract the column, and write it. ! do read ( input_unit, '(a)', iostat = ios ) line if ( ios /= 0 ) then exit end if call word_find ( line, colnum, word, nword ) if ( numarg >= 3 ) then if ( nword > 0 ) then write ( output_unit, '(a)' ) word(1:nword) else nmiss = nmiss + 1 write ( output_unit, * ) ' ' end if else if ( nword > 0 ) then write ( *, '(a)' ) word(1:nword) else nmiss = nmiss + 1 write ( *, '(a)' ) ' ' end if end if end do if ( numarg >= 3 ) then close ( unit = output_unit ) end if close ( unit = input_unit ) if ( nmiss > 0 ) then write ( *, '(a)' ) ' ' write ( *, '(a)' ) 'COLUMN - Warning.' write ( *, '(a,i6)' ) ' Number of lines missing data = ', nmiss end if stop end subroutine get_unit ( iunit ) ! !******************************************************************************* ! !! GET_UNIT returns a free FORTRAN unit number. ! ! ! Discussion: ! ! A "free" FORTRAN unit number is an integer between 1 and 99 which ! is not currently associated with an I/O device. A free FORTRAN unit ! number is needed in order to open a file with the OPEN command. ! ! Modified: ! ! 02 March 1999 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Output, integer IUNIT. ! ! If IUNIT = 0, then no free FORTRAN unit could be found, although ! all 99 units were checked (except for units 5 and 6). ! ! Otherwise, IUNIT is an integer between 1 and 99, representing a ! free FORTRAN unit. Note that GET_UNIT assumes that units 5 and 6 ! are special, and will never return those values. ! implicit none ! integer i integer ios integer iunit logical lopen iunit = 0 do i = 1, 99 if ( i /= 5 .and. i /= 6 ) then inquire ( unit = i, opened = lopen, iostat = ios ) if ( ios == 0 ) then if ( .not. lopen ) then iunit = i return end if end if end if end do return end subroutine s_to_i ( s, ival, ierror, last ) ! !******************************************************************************* ! !! S_TO_I reads an integer value from a string. ! ! ! Modified: ! ! 28 June 2000 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) S, a string to be examined. ! ! Output, integer IVAL, the integer value read from the string. ! If STRING is blank, then IVAL will be returned 0. ! ! Output, integer IERROR, an error flag. ! 0, no error. ! 1, an error occurred. ! ! Output, integer LAST, the last character of S used to make IVAL. ! implicit none ! character c integer i integer ierror integer isgn integer istate integer ival integer last character ( len = * ) s ! ierror = 0 istate = 0 isgn = 1 ival = 0 do i = 1, len_trim ( s ) c = s(i:i) ! ! Haven't read anything. ! if ( istate == 0 ) then if ( c == ' ' ) then else if ( c == '-' ) then istate = 1 isgn = -1 else if ( c == '+' ) then istate = 1 isgn = + 1 else if ( lle ( '0', c ) .and. lle ( c, '9' ) ) then istate = 2 ival = ichar ( c ) - ichar ( '0' ) else ierror = 1 return end if ! ! Have read the sign, expecting digits. ! else if ( istate == 1 ) then if ( c == ' ' ) then else if ( lle ( '0', c ) .and. lle ( c, '9' ) ) then istate = 2 ival = ichar ( c ) - ichar ( '0' ) else ierror = 1 return end if ! ! Have read at least one digit, expecting more. ! else if ( istate == 2 ) then if ( lle ( '0', c ) .and. lle ( c, '9' ) ) then ival = 10 * ival + ichar ( c ) - ichar ( '0' ) else ival = isgn * ival last = i - 1 return end if end if end do ! ! If we read all the characters in the string, see if we're OK. ! if ( istate == 2 ) then ival = isgn * ival last = len_trim ( s ) else ierror = 1 last = 0 end if return end subroutine timestamp ( ) ! !******************************************************************************* ! !! TIMESTAMP prints the current YMDHMS date as a time stamp. ! ! ! Example: ! ! May 31 2001 9:45:54.872 AM ! ! Modified: ! ! 31 May 2001 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! None ! implicit none ! character ( len = 8 ) ampm integer d character ( len = 8 ) date integer h integer m integer mm character ( len = 9 ), parameter, dimension(12) :: month = (/ & 'January ', 'February ', 'March ', 'April ', & 'May ', 'June ', 'July ', 'August ', & 'September', 'October ', 'November ', 'December ' /) integer n integer s character ( len = 10 ) time integer values(8) integer y character ( len = 5 ) zone ! call date_and_time ( date, time, zone, values ) y = values(1) m = values(2) d = values(3) h = values(5) n = values(6) s = values(7) mm = values(8) if ( h < 12 ) then ampm = 'AM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Noon' else ampm = 'PM' end if else h = h - 12 if ( h < 12 ) then ampm = 'PM' else if ( h == 12 ) then if ( n == 0 .and. s == 0 ) then ampm = 'Midnight' else ampm = 'AM' end if end if end if write ( *, '(a,1x,i2,1x,i4,2x,i2,a1,i2.2,a1,i2.2,a1,i3.3,1x,a)' ) & trim ( month(m) ), d, y, h, ':', n, ':', s, '.', mm, trim ( ampm ) return end subroutine word_find ( s, iword, word, nchar ) ! !******************************************************************************* ! !! WORD_FIND finds the word of a given index in a string. ! ! ! Discussion: ! ! A "word" is any string of nonblank characters, separated from other ! words by one or more blanks or TABS. ! ! Modified: ! ! 23 August 1998 ! ! Author: ! ! John Burkardt ! ! Parameters: ! ! Input, character ( len = * ) S, the string to be searched. ! ! Input, integer IWORD, the index of the word to be ! searched for. If IWORD is positive, then the IWORD-th ! word is sought. If IWORD is zero or negative, then ! assuming that the string has N words in it, the ! N+IWORD-th word will be sought. ! ! Output, character ( len = * ) WORD, the IWORD-th word of the ! string, or ' ' if the WORD could not be found. ! ! Output, integer NCHAR, the number of characters in WORD, ! or 0 if the word could not be found. ! implicit none ! integer i integer iblank integer ihi integer ilo integer iword integer jhi integer jlo integer jword integer kword integer lchar integer nchar character ( len = * ) s character, parameter :: TAB = char ( 9 ) character ( len = * ) word ! ilo = 0 ihi = 0 lchar = len_trim ( s ) if ( lchar <= 0 ) then return end if if ( iword > 0 ) then if ( s(1:1) == ' ' .or. s(1:1) == TAB ) then iblank = 1 jword = 0 jlo = 0 jhi = 0 else iblank = 0 jword = 1 jlo = 1 jhi = 1 end if i = 1 10 continue i = i + 1 if ( i > lchar ) then if ( jword == iword ) then ilo = jlo ihi = lchar nchar = lchar + 1 - jlo word = s(ilo:ihi) else ilo = 0 ihi = 0 nchar = 0 word = ' ' end if return end if if ( ( s(i:i) == ' ' .or. s(i:i) == TAB ) .and. iblank == 0 ) then jhi = i - 1 iblank = 1 if ( jword == iword ) then ilo = jlo ihi = jhi nchar = jhi + 1 - jlo word = s(ilo:ihi) return end if else if ( s(i:i) /= ' ' .and. s(i:i) /= TAB .and. iblank == 1 ) then jlo = i jword = jword + 1 iblank = 0 end if go to 10 else iblank = 0 kword = 1 - iword jword = 1 jlo = lchar jhi = lchar i = lchar 20 continue i = i - 1 if ( i <= 0 ) then if ( jword == kword ) then ilo = 1 ihi = jhi nchar = jhi word = s(ilo:ihi) else ilo = 0 ihi = 0 nchar = 0 word = ' ' end if return end if if ( ( s(i:i) == ' ' .or. s == TAB ) .and. iblank == 0 ) then jlo = i + 1 iblank = 1 if ( jword == kword ) then ilo = jlo ihi = jhi nchar = jhi + 1 - jlo word = s(ilo:ihi) return end if else if ( s(i:i) /= ' ' .and. s(i:i) /= TAB .and. iblank == 1 ) then jhi = i jword = jword + 1 iblank = 0 end if go to 20 end if end