Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Finding number of lines of a data file using command line

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.

like image 486
hbaromega Avatar asked Sep 11 '25 06:09

hbaromega


2 Answers

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.

like image 188
Vladimir F Героям слава Avatar answered Sep 13 '25 08:09

Vladimir F Героям слава


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!

like image 41
Pietro D'Antuono Avatar answered Sep 13 '25 10:09

Pietro D'Antuono