前回の続きです。自作の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$
一致しました。
つづく


コメント