change -- 文書ファイルの書き換え2015年09月06日 14:51

changeは、指定された文字列"原型"を 別の文字列"更新型"に置換します。

     change 原型 更新型

更新型には繰り返し記号"#"を含ませることができる。"#"は原型を表す。

     change foo #bar
とすれば、出現した"foo"は、"foobar"に置き換えられる。

changeはfindで使用したルーチンを利用して作成してある。まずは、メインルーチンから。

RATFOR版は以下の通り。

# change -- change "from" into "to"
      character lin(MAXLINE+1),new(MAXLINE+1),pat(MAXPAT),sub(MAXPAT)
      character arg(MAXARG)
      integer amatch,addset,getarg,getlin,getpat,getsub
      integer i,junk,k,lastm,m

      if (getarg(1,arg,MAXARG) == EOF)
          call error('usage: change from to.')
      if (getpat(arg,pat) == ERR)
          call error('illigal from pattern.')
      if (getarg(2,arg,MAXARG))
          arg(1) = EOS
      if ( getsub(arg,sub) == ERR)
          call error('illigal to.')

      while (getlin(lin,STDIN) .ne. EOF) {
          k = 1
          lastm = 0
          for (i = 1; lin(i) != EOS; ) {
              m = amatch(lin,i,pat)
              if (m > 0 & lastm != m) # replace matched text
                  call catsub(lin,i,m,sub,new,k,MAXLINE+1)
                  lastm = m
                  }
              if (m == 0 | m == i) {
                  junk = addset(lin(i),new,k,MAXLINE+1)
                  i = i + 1
                  }
              else
                  i = m
              }
          if (addset(EOS,new,k,MAXLINE+1) == NO) {
              k = MAXLINE + 1
              junk = addset(EOS,new,k,MAXLINE+1)
              call remark('line truncated.')
              call putlin(new,ERROUT)
              call fputc(ERROUT,NEWLINE)
              }
          call putlin(new,STDOUT)
          }
      stop
      end

WATCOM Fortran77版は下記の通り。

c change -- change "from" into "to"
      integer*1 lin(81+1),new(81+1),pat(81),sub(256) ! MAXLINE(81) MAXPAT(81)
      integer*1 arg(81)                 ! MAXARG(81)
      integer amatch,addset,getarg,getlin,getpat,getsub
      integer i,junk,k,lastm,m

      call initfile()

      if (getarg(1,arg,81) .eq. -1) then ! MAXARG(81) EOF(-1)
          call error('usage: change from to.')
      end if
      if (getpat(arg,pat) .eq. -1 ) then ! EOF(-1)
          call error('illigal from pattern.')
      end if
      if (getarg(2,arg,81) .eq. -1) then ! MAXLARG(81) EOF(-1)
          arg(1) = -2                  ! EOS(-2)
      end if
      if ( getsub(arg,sub) .eq. -1) then ! ERR(-1)
          call error('illigal to.')
      end if

      while (getlin(lin,5) .ne. -1) do  ! STDIN(5) EOF(-1)
          k = 1
          lastm = 0
          i = 1
          while (lin(i) .ne. -2) do     ! EOS(-2)
              m = amatch(lin,i,pat)
              if ((m .gt. 0) .and. (lastm .ne. m)) then ! replace matched text
                  call catsub(lin,i,m,sub,new,k,81+1) ! MAXLINE(81)
                  lastm = m
              end if
              if ((m .eq. 0) .or. (m .eq. i)) then
                  junk = addset(lin(i),new,k,81+1) ! MAXLINE(81)
                  i = i + 1
              else
                  i = m
              end if
          end while
          if (addset(-2,new,k,81+1) .eq. 0) then ! EOS(-2) NAXLINE(81) NO(0)
              k = 81+1                  ! MAXLINE(81)
              junk = addset(-2,new,k,81+1) ! EOS(-2) NAXLINE(81)
              call remark('line truncated.')
              call putlin(new,6)        ! ERROUT(6)
              call fputc(6,10)          ! ERROUT(6) NEWLINE(10)
          end if
          call putlin(new,6)
      end while
      stop
      end

下請けルーチンgetsub()は、置き換え文型を組み立てる。

RATFOR版は下記の通り。

# getsub -- get substitution pattern into sub
      integer function getsub(arg,sub)
      character arg(MAXARG),sub(MAXPAT)
      integer maksub

      getsub = maksub(arg,1,EOS,sub)
      return
      end

WATCOM Fortran77版は下記の通り。

c getsub -- get substitution pattern into sub
      integer function getsub(arg,sub)
      integer*1 arg(81),sub(81)         ! MAXARG(81) MAXPAT(81)
      integer maksub

      getsub = maksub(arg,1,-2,sub)     ! EOS(-2)
      return
      end

maksub()は、置き換え文字列を作成します。繰り返し記号"#"は、特別な記号に置き換えられます。

RATFOR版は下記の通り。

# maksub -- make subtitution string in sub
      integer function maksub(arg,from,delim,sub)
      character arg(MAXARG),delim,sub(MAXPAT)
      integer from
      character esc
      integer addset,i,j,junk

      j = 1
      for (i = from; arg(i) != delim & arg(i) != EOS; i = i + 1)
          if (arg(i) == SHARP 
              junk = addset(DITTO,sub,j,MAXPAT)
          else
              junk = addset(esc(arg,i),sub,j,MAXPAT)
      if (arg(i) != delim) then # missing delimiter
          maksub = ERR
      else if (.not. addset(EOS,sub,j,MAXPAT)) then # no room
          maksub = ERR
      else
          maksub = i
      return
      end

WATCOM Fortran77版は下記の通り。

c maksub -- make subtitution string in sub
      integer function maksub(arg,from,delim,sub)
      integer*1 arg(81),delim,sub(81)   ! MAXARG(81) MAXPAT(81)
      integer from
      integer*1 esc
      integer addset,i,j,junk

      j = 1
      i = from
      while ((arg(i) .ne. delim) .and. (arg(i) .ne. -2)) do  ! EOS(-2)
          if (arg(i) .eq. 35) then      ! SHARP(35 '#')
              junk = addset(-3,sub,j,81) ! DITTO(-3) MAXPAT(81)
          else
              junk = addset(esc(arg,i),sub,j,81) ! MAXPAT(81)
          end if
          i = i + 1
      end while
      if (arg(i) .ne. delim) then       ! missing delimiter
          maksub = -1                   ! ERR(-1)
      else if (addset(-2,sub,j,81) .eq. 0) then ! no room ! EOS(-2) MAXPAT81) NO(0)
          maksub = -1                   ! ERR(-1)
      else
          maksub = i
      end if
      return
      end

catsub()で、置き換えられた文字列を出力用文字列に追加します。 繰り返し記号が出てきたら、まず原型を追加します。

RATFOR版は下記の通り。

# catsub -- add replacement text to end of new
      subroutine catsub(lin,from,to,sub,new,k,maxnew)
      character lin(MAXLINE+1),sub(CMAXPAT),new(maxnew)
      integer from,to,k,maxnew
      integer addset,i,j,junk

      for (i = 1; sub(i) != EOS; i = i + 1) do
          if (sub(i) == DITTO)
              for (j = from; j < to; j = j + 1) 
                  junk = addset(lin(j),new,k,maxnew)
          else
              junk = addset(sub(i),new,k,maxnew)
      return
      end

WATCOM Fortran77版は下記の通り。

c catsub -- add replacement text to end of new
      subroutine catsub(lin,from,to,sub,new,k,maxnew)
      integer*1 lin(81+1),sub(81),new(maxnew) ! MAXLINE(81) MAXPAT(81)
      integer from,to,k,maxnew
      integer addset,i,j,junk

      i = 1
      while (sub(i) .ne. -2) do         ! EOS(-2)
          if (sub(i) .eq. -3) then      ! DITTO(-3)
              j = from
              while (j .lt. to) do
                  junk = addset(lin(j),new,k,maxnew)
                  j = j + 1
              end while
          else
              junk = addset(sub(i),new,k,maxnew)
          end if
          i = i + 1
      end while
      return
      end

edit -- 文書編集2015年09月23日 11:56

文書編集プログラム"edit"です。editは、行単位のエディターです。以下のようにして起動します。

  1. edit
  2. edit ファイル名

2は、ファイルをバッファーに読み込みます。

このエディターの指令には以下のものがあります。

  • [[開始行][,終了行]]p 印刷指令

    指定された範囲を印刷する。ここで、開始行、終了行には、"."現在行、"$"最後の行",行番号、 文脈検索が使える。文脈検索は、"/文字列/"現在行から初めて前方検索と、 "\文字列\"現在行の一つ手前から始めて後方検索とがある。

    たとえば、

         1p
    
    は、一行目を印刷する。
         p
    
    は、現在行を印刷する。
         1,.p
    
    は、1行目から現在行までを印刷する。現在行の前後を印刷するには、
         .-5,.+5p
    
    とする。
         \function\,/end/p
    
    は。現在行を含む関数全体を印刷する。
  • [[開始行][,終了行]]d 削除指令

    開始行から終了行までを削除する。

         d
    
    は、現在行が削除される。
         1,$d
    

    は、すべての行が削除される。

         .,$d
         p
    
    とすれば、現在行から最終行まで削除され、新しく最後の行になった行を印刷する。
  • s/元の文字列/置換後の文字列/ 置換指令

    置換指令は、"元の文字列"を"置換後の文字列"に置き換える。また、g指定をつけることができ、

         s/元の文字列/置換後の文字列/g
    
    とすれば、行全体に対して置換指令を実行できる。
         s/$/文字列/
    
    は、行末に文字列を追加する。また、
         s/%/文字列/
    
    は、行頭に文字列を挿入する。

    文脈探索、置換指令で最後に使われた文型は記憶されている。そこで、

         /ofrmat/s//format/p
         //s//format/p
         //s//format/p
         .....
    
    とすれば、"ofrmat"を順次見つけて"format"に置き換え確認の印刷をすることができる。
  • [開始行]a 付加指令

    開始行の後に行を追加する。

         $a
    

    は、行末に行を追加する。

         $a
         anything you want to type
         except a line containing only a .
         as in the following line
         .
    

    バッファの先頭に追加するときは、0aとすればよい。行番号が指定されていなければ、 現在行の次にそうに追加される。

  • [開始行]i 挿入指令

    a指令と同じだが、開始号の直前に行が挿入される。

  • [[開始行][,終了行]]c 変更指令

    変更指令は開始行から終了行までを、入力された行と置き換える。

  • [[開始行][,終了行]]m移動先 移動指令

    移動指令は、開始行から終了行までを移動先の次へ移動させる。

  • [開始行]r ファイル名 読み込み指令

    は、ファイルを開始行の次にファイルを読み込む。

  • [[開始行][,終了行]w ファイル名 書き込み指令

    は、開始証から終了行までをファイルに書き出す。

  • q 終了指令

    は、エディターを終了する。ファイルへの書き込みは行わないので、w指令を実行しておく必要がある。

    a,c,i,q以外の編集指令の前には、広域指定部gをつけることができる。

  • g/文型/指令

    は、「文型」を含むすべての行に対して、指令を実行する。

    このほかに、x指定、除外がある。

  • x/文型/指令

    は、文型を含む行以外に指令を実行する。