-bオプションに対応したcutコマンドを作成しました。
takk@deb9:~$ cat -n cut6.f
     1        PROGRAM MAIN
     2          CHARACTER*100 LINE
     3          INTEGER DISP_LOC(100),N
     4          CHARACTER*100 ARGS
     5
     6          N = IARGC()
     7          DO 300 I=1,N
     8            CALL GETARG(I,ARGS)
     9
    10            IF(ARGS(1:2).EQ.'-b') THEN
    11              CALL B_OPT(ARGS(3:),DISP_LOC)
    12            ELSE
    13              OPEN(UNIT=10,FILE=ARGS(1:INDEX(ARGS,' ')-1),
    14       1      STATUS='OLD',
    15       2      ACCESS='SEQUENTIAL')
    16     10       READ(10,*,END=100) LINE
    17              CALL CUT(LINE,DISP_LOC)
    18              GOTO 10
    19    100       CLOSE(10,STATUS='KEEP')
    20            END IF
    21    300 CONTINUE
    22            STOP
    23        END
    24
    25        SUBROUTINE B_OPT(B_OPT_STRING,DISP_LOC)
    26          CHARACTER*100 B_OPT_STRING
    27          CHARACTER*100 SSTRING1(10),SSTRING2(10)
    28          INTEGER I,SSIZE1,SSIZE2,K,L,M
    29          INTEGER DISP_LOC(100)
    30
    31          DO 10000 I=1,100
    32            DISP_LOC(I) = 0
    33  10000   CONTINUE
    34
    35          CALL SPLIT(B_OPT_STRING,',', SSTRING1,SSIZE1)
    36          DO 10200 I=1,SSIZE1
    37            CALL SPLIT(SSTRING1(I),'-', SSTRING2,SSIZE2)
    38            IF(SSIZE2.EQ.1) THEN
    39              READ(SSTRING1(I),*) L
    40              DISP_LOC(L) = 1
    41            ELSE
    42              READ(SSTRING2(1),*) L
    43              READ(SSTRING2(2),*) M
    44              DO 10100 K=L,M
    45                DISP_LOC(K) = 1
    46  10100       CONTINUE
    47            END IF
    48  10200   CONTINUE
    49        END
    50
    51        SUBROUTINE SPLIT(SRC,SEP,DEST,SPLIT_SIZE)
    52          CHARACTER*100 SRC
    53          CHARACTER*1 SEP
    54          CHARACTER*100 DEST(10)
    55          INTEGER IND,S1,S2,RSLT,SPLIT_SIZE
    56          IND = 0
    57          S2=-1
    58          I = 1
    59  20100   RSLT = INDEX(SRC(IND+1:),SEP)
    60          IF(RSLT.NE.0) THEN
    61            S1 = IND+1
    62            IND = IND + RSLT
    63            S2 = IND-1
    64            DEST(I) = SRC(S1:S2)
    65            I = I + 1
    66            GOTO 20100
    67          END IF
    68          DEST(I) = SRC(S2+2:)
    69          SPLIT_SIZE = I
    70          RETURN
    71        END
    72
    73        SUBROUTINE CUT(LINE,DISP_LOC)
    74          INTEGER DISP_LOC(100)
    75          CHARACTER*100 LINE
    76          DO 30100 I=1,100
    77            IF(DISP_LOC(I).EQ.1) THEN
    78              WRITE(*,31000) LINE(I:I)
    79            END IF
    80            IF(LINE(I:I).EQ.' ') THEN
    81              WRITE(*,*) ''
    82              GOTO 30200
    83            END IF
    84  30100   CONTINUE
    85  30200   RETURN
    86  31000   FORMAT(A$)
    87        END
takk@deb9:~$
73行目のCUT関数が、列抽出する関数です。100列分配列を確認して、1がはいっていたら、部分文字列の抽出をします。空白が出現したら、文字列の終端とみなして、改行するためにWRITE(*,*) ”を実行しています。
動くでしょうか。GDBを使ってみます。
takk@deb9:~$ gfortran -g -fdollar-ok cut6.f takk@deb9:~$ gdb a.out
パラメータを設定し、パラメータ数の取得関数前まで実行します。
(gdb) set args -b2-3,5 x00 (gdb) l 1 PROGRAM MAIN 2 CHARACTER*100 LINE 3 INTEGER DISP_LOC(100),N 4 CHARACTER*100 ARGS 5 6 N = IARGC() 7 DO 300 I=1,N 8 CALL GETARG(I,ARGS) 9 10 IF(ARGS(1:2).EQ.'-b') THEN (gdb) b 6 Breakpoint 1 at 0x147b: file cut6.f, line 6. (gdb) run Starting program: /home/takk/a.out -b2-3,5 x00 Breakpoint 1, MAIN__ () at cut6.f:6 6 N = IARGC() (gdb)
パラメータ数は2ですので、合ってます。
(gdb) n 7 DO 300 I=1,N (gdb) p N $1 = 2 (gdb)
1を設定する配列の位置も、-bで指定した通りとなっています。
(gdb) n 8 CALL GETARG(I,ARGS) (gdb) 10 IF(ARGS(1:2).EQ.'-b') THEN (gdb) 11 CALL B_OPT(ARGS(3:),DISP_LOC) (gdb) 7 DO 300 I=1,N (gdb) p DISP_LOC $2 = (0, 1, 1, 0, 1, 0, 0, ~ (gdb)
ファイルから読み込んだ文字列もOKです。
(gdb) n 8 CALL GETARG(I,ARGS) (gdb) 10 IF(ARGS(1:2).EQ.'-b') THEN (gdb) 15 2 ACCESS='SEQUENTIAL') (gdb) 16 10 READ(10,*,END=100) LINE (gdb) 17 CALL CUT(LINE,DISP_LOC) (gdb) p line $3 = '10010', ' ' <repeats 95 times> (gdb)
(gdb) n 000 18 GOTO 10 (gdb) 16 10 READ(10,*,END=100) LINE (gdb) 17 CALL CUT(LINE,DISP_LOC) (gdb) s cut (line=..., disp_loc=..., _line=100) at cut6.f:76 76 DO 30100 I=1,100 (gdb) n 77 IF(DISP_LOC(I).EQ.1) THEN (gdb) 80 IF(LINE(I:I).EQ.' ') THEN (gdb) 76 DO 30100 I=1,100 (gdb) 77 IF(DISP_LOC(I).EQ.1) THEN (gdb) 78 WRITE(*,31000) LINE(I:I) (gdb) 080 IF(LINE(I:I).EQ.' ') THEN (gdb)
実行結果を見てしまった方が早そうです。
takk@deb9:~$ ./a.out -b1,2,3,4 x00 1001 1011 1021 1031 1041 1051 1061 1071 1081 1091 takk@deb9:~$ ./a.out -b1-4 x00 1001 1011 1021 1031 1041 1051 1061 1071 1081 1091 takk@deb9:~$ ./a.out -b2-3,5 x00 000 010 020 030 040 050 060 070 080 090 takk@deb9:~$
上手く行きました。


コメント