There is a conventional way to read each line one by one and check iostat hits nonzero or negative value at every reading. However, I would like to call system(command) routine and
use wc -l command to count the number of and then want to allocate the dimension of the array where I want to put the data. For the example, I am printing the number of lines in both ways:
Program Test_reading_lines
    integer:: count,ios, whatever
    character(LEN=100):: command
    Print*,'Reading number of lines in a standard way'
    count=0
    open (10, file='DATA_FILE')
     Do
           read (10,*,iostat=ios) whatever
           if (ios/=0) exit     
         count=count+1
      End Do
    close(10)
    Print*,'Number of lines =', count
    Print*,'Reading number of lines using shell command'
    command='cat DATA_FILE | wc -l'
    call system(command)
    Print*,'Number of lines =','< ? >' 
    End Program Test_reading_lines
Unfortunately, in the latter case, can I assign a variable like count as in the standard case? That is, I want to print a variable instead of '< ? >' in the last print command.
This is not possible in a straightforward way. You could redirect the output of the command to a file, then open it and read it http://compgroups.net/comp.lang.fortran/how-to-get-the-output-of-call-system-in-a-v/216294
Or use some even more sophisticated features of the Unix functions and call its C API (see the first answer in that thread).
The EXECUTE_COMMAND_LINE() also does not have any feature to read the output of the command directly.
If you want to use the Unix command $ wc -l, you could call the Fortran subroutine execute_command_line which is common to many Fortran compilers, gfortran included.
Here is a working example which computes the number of lines, nlines, of a file called style.gnuplot and then uses nlines to append some rows to style.gnuplot by overwriting the last one.
PROGRAM numLines
    IMPLICIT NONE
    integer, parameter :: n = 100
    integer :: i, nLines
    real, parameter :: x0 = -3.14, xEnd = 3.14
    real :: dx
    real, dimension (:), allocatable :: x, fun
    allocate(x(0:n)) ! Allocate the x array
    allocate(fun(0:n)) ! Allocate the fun array
    dx = abs(xEnd-x0)/n
    x(0:n) = [(x0+i*dx, i = 0,n)] ! Create the x array
    fun(0:n) = [(sin(x0+i*dx), i = 0,n)] ! Create the fun array
    open(unit=1,file="plotFunction.dat")
        DO i=0,size(x)-1
            write(1,*) x(i), ' ', fun(i) ! Save the function to a file to plot
        END DO
    close(unit=1)
    deallocate(x) ! Deallocate the x array
    deallocate(fun) ! Deallocate the fun array
    open(unit=7, file="style.gnuplot")
        write(7,*) "set title 'y = sin(x)' font 'times, 24'"
        write(7,*) "set tics font 'times, 20'"
        write(7,*) "set key font 'times,20'"
        write(7,*) "set grid"
        write(7,*) "set key spacing 1.5"
        write(7,*) "plot '<cat' u 1:2 w l lw 2  linecolor rgb 'orange' notitle "
    close(unit=7)
    CALL execute_command_line("wc -l style.gnuplot | cut -f1 -d' ' > nlines.file") ! COunt the lines
    open(unit=1,file='nlines.file')
        read(1,*) nlines ! Here the number of lines is saved to a variable
    close(unit=1)
    CALL execute_command_line("rm nlines.file") ! Remove nlines.file
    CALL execute_command_line("cat plotFunction.dat | gnuplot -p style.gnuplot") ! Show the plot within the executable
    open(unit=7,file="style.gnuplot")
        DO i = 1,nLines-1 
            read(7,*) ! Read the file untile the penultimate row,
        END DO        ! then append the other rows
        write(7,*) "set object rectangle at -3.14,0 size char 1, char 1", & 
                                                                    " fillcolor rgb 'blue' fillstyle solid border lt 2 lw 1.5"
        write(7,*) "set object rectangle at 0,0 size char 1, char 1", & 
                                                                    " fillcolor rgb 'blue' fillstyle solid border lt 2 lw 1.5"
        write(7,*) "set object rectangle at 3.14,0 size char 1, char 1", & 
                                                                    " fillcolor rgb 'blue' fillstyle solid border lt 2 lw 1.5"
        write(7,*) "plot 'plotFunction.dat' u 1:2 w l lw 2  linecolor rgb 'orange' notitle"
    close(unit=7)
    CALL execute_command_line("gnuplot -p 'style.gnuplot'") ! Load again style.gnulot with the appended lines
END PROGRAM numLines
My code might not be elegant, but it seems to work!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With