Created
May 14, 2009 09:43
-
-
Save tsupo/111589 to your computer and use it in GitHub Desktop.
cut
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* | |
| * cut.c | |
| * | |
| * cut --- 行の中から指定フィールドを切り出す | |
| * | |
| * 形式 | |
| * (1) cut -c<フィールド> [filename ...] | |
| * (2) cut -f<フィールド> [-d<セパレータ>] [-s] | |
| * 機能 | |
| * (1) 空白文字(スペース)をフィールドの区切りとみなし、 | |
| * 指定フィールドを切り出す | |
| * (2) 指定されたセパレータをフィールドの区切りとみな | |
| * し、指定フィールドを切り出す。-dオプションでセ | |
| * パレータが指定されない場合は、スペースおよびタ | |
| * ブをセパレータとみなす。-sオプションが指定され | |
| * る場合は、セパレータの含まれない行はそのまま出 | |
| * 力するが、指定されない場合は、セパレータの含ま | |
| * れない行は捨てられる。なお、セパレータは文字列 | |
| * でも構わない(UNIX標準の cut (1) はセパレータは | |
| * 単一の文字でなければならない) | |
| * フィールドの指定の仕方 | |
| * 数 "数"番目のフィールド | |
| * 数- "数"番目のフィールドから行の終わりまで | |
| * 数1-数2 "数1"番目のフィールドから"数2"番目のフィールドまで | |
| * -数 行の始めから"数"番目のフィールドまで | |
| * 数1,数2 "数1"番目のフィールドと"数2"番目のフィールド | |
| * を、それぞれ切り出す。切り出したいフィールドがいくつもある場 | |
| * 合は、例えば | |
| * 数1-数2,数3,数4-数5,数6,数7,数8- | |
| * ("数1"番目から"数2"番目までと"数3"番目、 "数4"番目から | |
| * "数5"番目まで、さらに"数6"番目と"数7"番目、および"数8" | |
| * 番目から行の終わりまで を切り出す) | |
| * のように、フィールド指定を組合わせることもできる | |
| */ | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #define MAXFIELD (BUFSIZ-1) | |
| #ifndef NUL | |
| #define NUL '\0' | |
| #endif | |
| char separator[BUFSIZ]; | |
| char valid[MAXFIELD+1]; | |
| /* mode | |
| * 7 6 5 4 3 2 1 0 | |
| * +-+-+-+-+-+-+-+-+ | |
| * | | | | | | | | | | |
| * +-+-+-+-+-+-+-+-+ | |
| * | | | | | |
| * | | | +---- specified -s option (1) or not (0) | |
| * | | +------ specified -f (1) or not (0) | |
| * | +-------- specified -c (1) or not (0) | |
| * +---------- specified -d<delimiter> (1) or not (0) | |
| */ | |
| #define SMODE 0x01 | |
| #define FMODE 0x02 | |
| #define CMODE 0x04 | |
| #define DMODE 0x08 | |
| #define TRUE (1) | |
| #define FALSE (!TRUE) | |
| /* void setField(); */ | |
| void ccut(), ffcut(), fdcut(); | |
| #if 0 | |
| void | |
| cut( FILE *fp, unsigned char mode ) | |
| { | |
| ( mode & CMODE ) ? ccut( fp, mode ) : fcut( fp, mode ); | |
| } | |
| void | |
| fcut( FILE *fp, unsigned char mode ) | |
| { | |
| ( mode & DMODE ) ? fdcut( fp, mode ) : ffcut( fp, mode ); | |
| } | |
| #else | |
| #define cut(fp,mode) (((mode)&CMODE)?ccut((fp),(mode)):fcut((fp),(mode))) | |
| #define fcut(fp,mode) (((mode)&DMODE)?fdcut((fp),(mode)):ffcut((fp),(mode))) | |
| #endif | |
| void | |
| setField( char *p ) | |
| { | |
| char *q; | |
| if ( p && (((*p >='0') && (*p <= '9')) || (*p == ',') || (*p == '-')) ) { | |
| if ( (q = strchr( p, ',' )) != NULL ) { | |
| char buf[BUFSIZ]; | |
| if ( *p == ',' ) { | |
| p++; | |
| } | |
| while ( (q = strchr( p, ',' )) != NULL ) { | |
| if ( *p == ',' ) { | |
| p++; | |
| continue; | |
| } | |
| strncpy( buf, p, q - p ); | |
| buf[q - p] = NUL; | |
| setField( buf ); | |
| p = q + 1; | |
| } | |
| if ( p ) { | |
| setField( p ); | |
| } | |
| } | |
| else if ( (q = strchr( p, '-' )) != NULL ) { | |
| int start = 0; | |
| int end = MAXFIELD - 1; | |
| int i; | |
| if ( *p == '-' ) { | |
| if ( *(p + 1) && (*(p + 1) >= '0') && (*(p + 1) <= '9') ) { | |
| end = atol( p + 1 ); | |
| } | |
| } | |
| else if ( (*p >= '0') && (*p <= '9') ) { | |
| start = atol( p ); | |
| p = q + 1; | |
| if ( p && (*p >= '0') && (*p <= '9') ) { | |
| end = atol( p ); | |
| } | |
| } | |
| if ( (0 <= start) && (start <= end) && (end < MAXFIELD) ) { | |
| for ( i = start; i <= end; i++ ) { | |
| valid[i] = TRUE; | |
| } | |
| } | |
| } | |
| else { | |
| int field = atoi( p ); | |
| if ( (field >= 0) && (field < MAXFIELD) ) { | |
| valid[field] = TRUE; | |
| } | |
| } | |
| } | |
| } | |
| void | |
| main( argc, argv ) | |
| int argc; | |
| char *argv[]; | |
| { | |
| unsigned char mode = 0x00; | |
| int i, fcnt = 0; | |
| FILE *fp; | |
| for ( i = 1; i < argc; i++ ) { | |
| if ( argv[i][0] == '-' ) { | |
| switch ( argv[i][1] ) { | |
| case 's': | |
| mode = !((mode & SMODE) == SMODE) ? (mode | SMODE) | |
| : (mode & ~SMODE); | |
| break; | |
| case 'c': | |
| mode |= CMODE; | |
| setField( &argv[i][2] ); | |
| break; | |
| case 'f': | |
| mode |= FMODE; | |
| setField( &argv[i][2] ); | |
| break; | |
| case 'd': | |
| mode |= DMODE; | |
| strcpy( separator, &argv[i][2] ); | |
| break; | |
| case '-': | |
| break; | |
| default: | |
| fprintf( stderr, "cut: illegal option: <%s>.\n", argv[i] ); | |
| exit( 2 ); | |
| /* not reached */ | |
| break; | |
| } | |
| if ( argv[i][1] == '-' ) | |
| strcpy( argv[i], &argv[i][1] ); | |
| else | |
| continue; | |
| } | |
| if ( !( mode & (CMODE | FMODE) ) ) { | |
| fputs( "cut: too few argument.\n", stderr ); | |
| exit( 2 ); | |
| } | |
| if ( ( fp = fopen( argv[i], "r" ) ) == NULL ) { | |
| fprintf( stderr, "cut: cannot open <%s>.\n", argv[i] ); | |
| exit( 1 ); | |
| } | |
| cut( fp, mode ); | |
| fclose( fp ); | |
| fcnt++; | |
| } | |
| if ( fcnt == 0 ) { | |
| if ( !( mode & (CMODE | FMODE) ) ) { | |
| fputs( "cut: too few argument.\n", stderr ); | |
| exit( 2 ); | |
| } | |
| cut( stdin, mode ); | |
| } | |
| exit( 0 ); | |
| } | |
| void | |
| ccut( fp, mode ) | |
| FILE *fp; | |
| unsigned char mode; | |
| { | |
| char *p, buf[BUFSIZ], out[BUFSIZ]; | |
| int cnt, i; | |
| while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { | |
| cnt = 0; | |
| i = 0; | |
| out[i] = NUL; | |
| while ( *p ) { | |
| if ( *p == ' ' ) { | |
| if ( valid[cnt] == TRUE ) | |
| out[i++] = *p; | |
| cnt++; | |
| while ( *p && ( *p == ' ' ) ) | |
| p++; | |
| if ( !(*p) ) | |
| break; | |
| } | |
| if ( valid[cnt] == TRUE ) { | |
| out[i++] = *p; | |
| } | |
| p++; | |
| } | |
| if ( (i > 0) && (out[i - 1] != '\n') ) { | |
| out[i++] = '\n'; | |
| } | |
| out[i] = NUL; | |
| if ( out[0] != NUL ) | |
| fputs( out, stdout ); | |
| else if ( mode & SMODE ) | |
| fputs( buf, stdout ); | |
| } | |
| if ( fp == stdin ) | |
| clearerr( stdin ); | |
| } | |
| void | |
| ffcut( fp, mode ) | |
| FILE *fp; | |
| unsigned char mode; | |
| { | |
| char *p, buf[BUFSIZ], out[BUFSIZ]; | |
| int cnt, i; | |
| while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { | |
| cnt = 0; | |
| i = 0; | |
| out[i] = NUL; | |
| while ( *p ) { | |
| if ( ( *p == ' ' ) || ( *p == '\t' ) ) { | |
| if ( valid[cnt] == TRUE ) | |
| out[i++] = *p; | |
| cnt++; | |
| while ( *p && ( ( *p == ' ' ) && ( *p == '\t' ) ) ) | |
| p++; | |
| if ( !(*p) ) | |
| break; | |
| } | |
| if ( valid[cnt] == TRUE ) { | |
| out[i++] = *p; | |
| } | |
| p++; | |
| } | |
| if ( (i > 0) && (out[i - 1] != '\n') ) { | |
| out[i++] = '\n'; | |
| } | |
| out[i] = NUL; | |
| if ( out[0] != NUL ) | |
| fputs( out, stdout ); | |
| else if ( mode & SMODE ) | |
| fputs( buf, stdout ); | |
| } | |
| if ( fp == stdin ) | |
| clearerr( stdin ); | |
| } | |
| void | |
| fdcut( fp, mode ) | |
| FILE *fp; | |
| unsigned char mode; | |
| { | |
| char *p, buf[BUFSIZ], out[BUFSIZ]; | |
| int cnt, i; | |
| while ( ( p = fgets( buf, BUFSIZ - 1, fp ) ) != NULL ) { | |
| cnt = 0; | |
| i = 0; | |
| out[i] = NUL; | |
| while ( *p ) { | |
| if ( !strncmp( p, separator, strlen(separator) ) ) { | |
| if ( valid[cnt] == TRUE ) { | |
| if ( ( i == 0 ) || ( out[i-1] != ' ' ) ) | |
| out[i++] = ' '; | |
| } | |
| cnt++; | |
| p += strlen(separator); | |
| continue; | |
| } | |
| if ( valid[cnt] == TRUE ) | |
| out[i++] = *p; | |
| p++; | |
| } | |
| if ( (i > 0) && (out[i - 1] != '\n') ) { | |
| out[i++] = '\n'; | |
| } | |
| out[i] = NUL; | |
| if ( out[0] != NUL ) | |
| fputs( out, stdout ); | |
| else if ( mode & SMODE ) | |
| fputs( buf, stdout ); | |
| } | |
| if ( fp == stdin ) | |
| clearerr( stdin ); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment