前回の続きです。自作のtailの末尾Byte抽出を複数のファイルに対応します。
今回の自作tailで読み込ませるバイナリ作成。
takk@deb9:~/tmp$ echo 0 010203 | xxd -rp > a.bin takk@deb9:~/tmp$ echo 0 040506 | xxd -rp > b.bin takk@deb9:~/tmp$ od -tx1 a.bin 0000000 01 02 03 0000003 takk@deb9:~/tmp$ od -tx1 b.bin 0000000 04 05 06 0000003 takk@deb9:~/tmp$
本物tailの動きを確認します。
takk@deb9:~/tmp$ tail -c2 a.bin b.bin | od -tx1c 0000000 3d 3d 3e 20 61 2e 62 69 6e 20 3c 3d 3d 0a 02 03 = = > a . b i n < = = \n 002 003 0000020 0a 3d 3d 3e 20 62 2e 62 69 6e 20 3c 3d 3d 0a 05 \n = = > b . b i n < = = \n 005 0000040 06 006 0000041 takk@deb9:~/tmp$
行抽出と同じく、-cオプション指定時のByte抽出でも、
==> a.bin <==や==> b.bin <==といった見出しが表示されています。
この見出しを表示する処理と、ファイル数分ループする処理を、前回のプログラムに加えたのがこれです。
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 while(argc--){ 32 fname = *argv++; 33 printf("<== %s ==>\n",fname); 34 35 stat(fname, &fs); 36 37 len = fs.st_size < len ? fs.st_size : len; 38 39 fp=fopen(fname,"r"); 40 if(fseek(fp,-len,SEEK_END) != 0){ 41 perror("ERROR"); 42 } 43 while((c=fgetc(fp)) != -1){ 44 putchar(c); 45 } 46 fclose(fp); 47 } 48 49 return 0; 50 } takk@deb9:~/tmp$
31と33、47行目が、複数ファイル処理のために追加した箇所です。
ビルド後、実行します。
takk@deb9:~/tmp$ ./a.out -c2 a.bin b.bin | od -tx1c 0000000 3c 3d 3d 20 61 2e 62 69 6e 20 3d 3d 3e 0a 02 03 < = = a . b i n = = > \n 002 003 0000020 3c 3d 3d 20 62 2e 62 69 6e 20 3d 3d 3e 0a 05 06 < = = b . b i n = = > \n 005 006 0000040 takk@deb9:~/tmp$
なんとなく、たぶん合ってるのだろうけど、情報が多くて比較しにくいので、見出しを非表示にしてみましょう。
本物のtailコマンドでは、-qオプションで、見出しを非表示にできます。同じように、自作tailにも-qオプションを追加してみます。
takk@deb9:~/tmp$ cat -n t.c ~省略~ 16 int qflag=0; 17 18 while ((optch = getopt(argc, argv, "c:q")) != -1){ 19 switch (optch) { 20 case 'c': 21 len = atoi(optarg); 22 break; 23 case 'q': 24 qflag = 1; 25 break; 26 default: ~省略~ 35 while(argc--){ 36 fname = *argv++; 37 if(!qflag) 38 printf("<== %s ==>\n",fname); ~省略~ takk@deb9:~/tmp$
-qオプションの対応は、数行付け足すだけです。
-qオプションが指定されたら、qflagを1にして、qflagが1の場合は、見出しを表示しないようにします。
さて、-qオプションを使って結果をシンプルにできるようになったので、比較してみましょう。
自作tail。
takk@deb9:~/tmp$ ./a.out -qc2 a.bin b.bin | od -tx1 0000000 02 03 05 06 0000004 takk@deb9:~/tmp$
本物tail。
takk@deb9:~/tmp$ tail -qc2 a.bin b.bin | od -tx1 0000000 02 03 05 06 0000004 takk@deb9:~/tmp$
一致しました。
つづく
コメント