続きです。
前回のソースに、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$
つづく
コメント