Search code examples
awkvimsed

sed/awk/vim: how to replace variable in a function call


I have this piece of fortran code (there are 6 before call and 5 before &):

           call mpi_send( v(1), nx, MPI_DOUBLE_PRECISION,
          &               prev, myid-1, comm, ierr )

And I am looking for a way to extract nx and myid-1 to replace them by respectively cnt and tag (ideally aligned with call just above) like so:

           cnt = nx
           tag = myid-1
           call mpi_send( v(1), cnt, MPI_DOUBLE_PRECISION,
          &               prev, tag, comm, ierr )

cnt (or nx) is always the second argument of mpi_send. tag (or myid-1) is always the 5th argument of mpi_send.

I understand I have to play with the s substitute sed option, combined with capture, and "insert above" command... This may/could look like:

  sed -i '/mpi_send(.*, \(.*\), .*&.*, \(.*\)/{
s//\1/
i\
      cnt = \1
      tag = \2 
}' file.f

... Which doesn't work: I can't get a way to get that together.

EDIT

Ideally looking for a solution that could handle all cases like :

           call mpi_recv( mv_buf, nx, MPI_DOUBLE_PRECISION, prev, myid,
          &               comm, status, ierr )

That should be replaced by

           cnt = nx
           tag = myid
           call mpi_recv( mv_buf, cnt, MPI_DOUBLE_PRECISION, prev, tag,
          &               comm, status, ierr )

EDIT

Ideally need to handle lots of other slightly different changing cases (where patterns to replace may change) and where indentation may change in if blocks (6 before if, and so, more than 6 before call mpi_send).

         if ( myid .lt. nprocs-1 ) then
            call mpi_send( v((np-1)*nx+1), nx, MPI_DOUBLE_PRECISION,
        &                  next, myid+1, comm, ierr )
          endif

Can somebody help?


Solution

  • This ugly sed command should work for all functions whose names start with mpi_:

    sed -i.orig '/^ *call mpi_.*(/{
    N
    s/\( *\)\([^,]*,\)\([^,]*\),\(\([^,]*,\)\{2\}\)\([^,]*\)\(.*\)/\1cnt = \3\
    \1tag = \6\
    \1\2 cnt,\4 tag\7/
    }' file.f