自作のtail(その4)

続きです。

前回のソースに、getopt処理を追加します。リアルtail同様、-cでByteを指定して末尾データを抽出できるように修正。

takk@deb9:~/tmp$ cat -n t.c
     1	#include <stdio.h>
     2	#include <sys/types.h>	//stat
     3	#include <sys/stat.h>	//stat
     4	#include <unistd.h>	//stat
     5	#include <getopt.h>	//getopt
     6	#include <stdlib.h>	//atoi
     7	
     8	int main(int argc, char* argv[])
     9	{
    10		int c;
    11		FILE *fp;
    12		char *fname;
    13		struct stat fs;
    14		int len = 10;
    15		int optch;
    16	
    17		while ((optch = getopt(argc, argv, "c:")) != -1){
    18			switch (optch) {
    19			case 'c':   
    20				len = atoi(optarg);
    21				break;
    22			default:
    23				printf("parameter error\n");
    24				return 1;
    25			}
    26		}
    27	
    28		argv += optind;
    29		argc -= optind;
    30	
    31		fname = *argv++;
    32	
    33		stat(fname, &fs);
    34	
    35		len = fs.st_size < len ? fs.st_size : len;
    36	
    37		fp=fopen(fname,"r");
    38		if(fseek(fp,-len,SEEK_END) != 0){
    39			perror("ERROR");
    40		}
    41		while((c=fgetc(fp)) != -1){
    42			putchar(c);
    43		}
    44		fclose(fp);
    45	
    46		return 0;
    47	}
takk@deb9:~/tmp$ 

getopt.hを追加するのと、15~33行目当たりを追加、修正してます。

テスト用データは、100Byteぐらいのファイルを使います。

takk@deb9:~/tmp$ seq 100 | tac | perl -ne 'print chr'>a.bin
takk@deb9:~/tmp$ 

冒頭のソースをgccでビルド後、以下のコマンドで確認。-cで3Byte末尾を抽出します。
そのまま標準出力すると、文字にならないので、odでダンプして確認します。

takk@deb9:~/tmp$ ./a.out -c3 a.bin | od -tx1
0000000 03 02 01
0000003
takk@deb9:~/tmp$ 

も少し大きな数字を指定。

takk@deb9:~/tmp$ ./a.out -c35 a.bin | od -tx1 -Ad -w10
0000000 23 22 21 20 1f 1e 1d 1c 1b 1a
0000010 19 18 17 16 15 14 13 12 11 10
0000020 0f 0e 0d 0c 0b 0a 09 08 07 06
0000030 05 04 03 02 01
0000035
takk@deb9:~/tmp$ 

ファイルサイズを超えた値で確認。

takk@deb9:~/tmp$ ./a.out -c300 a.bin | od -tx1 -Ad -w10 
0000000 64 63 62 61 60 5f 5e 5d 5c 5b
0000010 5a 59 58 57 56 55 54 53 52 51
0000020 50 4f 4e 4d 4c 4b 4a 49 48 47
0000030 46 45 44 43 42 41 40 3f 3e 3d
0000040 3c 3b 3a 39 38 37 36 35 34 33
0000050 32 31 30 2f 2e 2d 2c 2b 2a 29
0000060 28 27 26 25 24 23 22 21 20 1f
0000070 1e 1d 1c 1b 1a 19 18 17 16 15
0000080 14 13 12 11 10 0f 0e 0d 0c 0b
0000090 0a 09 08 07 06 05 04 03 02 01
0000100
takk@deb9:~/tmp$ 

問題なさそう。

次は、複数ファイル指定できるようにします。
その前に、tailコマンドの動きを思い出します。tailで複数ファイルを指定すると、以下のようにそれぞれをファイルの末尾が抽出できます。見出しはheadと同じですね。

takk@deb9:~/tmp$ seq 20 | split -dl10
takk@deb9:~/tmp$ ls x*
x00  x01
takk@deb9:~/tmp$ tail -n5 x*
==> x00 <==
6
7
8
9
10

==> x01 <==
16
17
18
19
20
takk@deb9:~/tmp$ 

つづく

コメント

タイトルとURLをコピーしました