Поиск количества строк файла данных с помощью командной строки

Существует обычный способ чтения каждой строки по одной и проверки того, что iostat попадает в ненулевое или отрицательное значение при каждом чтении. Однако я хотел бы вызвать подпрограмму system(command) и использовать команду wc -l для подсчета количества, а затем выделить размер массива, в который я хочу поместить данные. Например, я печатаю количество строк в обоих направлениях:

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

К сожалению, в последнем случае можно ли присвоить переменную вида count как в стандартном случае? То есть я хочу напечатать переменную вместо '< ? >' в последней команде печати.


person hbaromega    schedule 26.09.2014    source источник
comment
Используйте тег fortran, в вашем вопросе нет ничего конкретного для fortran90. Даже если это было конкретно, используйте оба тега. Вполне вероятно, что из-за этого вы до сих пор не привлекали к себе внимания.   -  person Vladimir F    schedule 27.09.2014
comment
Спасибо @VladimirF, я буду иметь это в виду при отметке в следующий раз.   -  person hbaromega    schedule 27.09.2014


Ответы (2)


Это невозможно прямым путем. Вы можете перенаправить вывод команды в файл, затем открыть его и прочитать http://compgroups.net/comp.lang.fortran/how-to-get-the-output-of-call-system-in-a-v/216294

Или используйте некоторые еще более сложные функции функций Unix и вызовите его C API (см. первый ответ в этой ветке).

EXECUTE_COMMAND_LINE() также не имеет функции чтения вывода команды напрямую.

person Vladimir F    schedule 27.09.2014

Если вы хотите использовать команду Unix $ wc -l, вы можете вызвать подпрограмму Fortran execute_command_line, которая является общей для многих компиляторов Fortran, включая gfortran.

Вот рабочий пример, который вычисляет количество строк, nlines, в файле с именем style.gnuplot, а затем использует nlines для добавления некоторых строк в style.gnuplot, перезаписывая последнюю.

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

Мой код может быть не элегантным, но, похоже, он работает!

person Pietro D'Antuono    schedule 23.12.2016
comment
Да, это должно сработать. К сожалению, это косвенный способ, когда вам нужно сохранить вывод во внешний файл и прочитать его с Фортрана. - person Vladimir F; 23.12.2016
comment
Я понимаю. Каков основной недостаток использования этого решения? Это сильно увеличивает процессорное время? - person Pietro D'Antuono; 23.12.2016
comment
Ну и любой ввод-вывод диска занимает довольно много времени, конечно. Это зависит от того, заботитесь ли вы об этом в своем приложении. - person Vladimir F; 23.12.2016