-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:~$
上手く行きました。
コメント