grep 명령어 

 

- ./grep 정규표현식_패턴 파일명 ...
 
 
정규표현식 규칙
. : 한 문자
* : 선형 패턴 0회 이상 반복
? : 생략가능
\ : 메타문자

 

libc에서 제공하는 정규표현식 API
#include <sys/types.h>
#include <regex.h>
 
int regcomp(regex_t *reg, const char *pattern,
     int flags); : pattern에 든 정규표현식 문자열을 regex_t로 반환, 결과는 reg에
void regfree(regex_t *reg); : regcomp로 확보한 메모리를 해제
int regexec(const regex_t *reg, const char *string,
    size_t nmatch, regmatch_t pmatch[], int flags); : regex_t(패턴) + 문자열로 패턴찾음, 성공시 0 아니면 다른 값 반환
size_t regerror(int errcode, const regex_t *reg,
    char *msgbuf, size_t msgbuf_size); : regcomp서 에러발생시 에러 코드 반환, 이 에러코드를 메시지로 변환

 

 

grep 명령어 구현 코드 및 결과


static void do_grep(regex_t *pat, FILE *src);

int main(int argc, char *argv[])
{
    regex_t pat;
    int err;
    int i;
    
    if (argc < 2)
    {
        fputs("no pattern \n", stderr);
        exit(1);
    }

    err = regcomp(&pat, argv[1], REG_EXTENDED | REG_NOSUB | REG_NEWLINE);
    if (err != 0){
        char buf[1024];
        regerror(err, &pat, buf, sizeof buf);
        puts(buf);
        exit(1);
    }
    if (argc == 2){
        do_grep(&pat, stdin);
    }
    else {
        for (i = 2; i < argc; i++){
            FILE *f;
            
            f = fopen(argv[i], "r");
            if (!f){
                perror(argv[i]);
                exit(1);
            }
            do_grep(&pat, f);
            fclose(f);
        }
    }
    regfree(&pat);
    exit(0);
}


static void do_grep(regex_t *pat, FILE *src)
{
    char buf[4096];

    while (fgets(buf, sizeof buf, src))
    {
        if (regexec(pat, buf, 0, NULL, 0) == 0){
            fputs(buf, stdout);
        }
    }
}

 

 

리눅스 디렉터리 구조

- 최상위 디렉터리인 루트 /를 시작으로하며, 디렉터리 트리라고도 함.

 

 

/ : 최상위

/bin :  시스템 실행 파일(명령어) 보관  <-> /usr/bin : 일반 사용자를 위한 실행파일

/sbin : 관리자용 명령어

/lib : 시스템  라이브러리 디렉터리       <->  /usr/lib : 유저 라이브러리 디렉터리

/usr : 여러 컴퓨터에서 같이 쓸수있는 sw 파일 보관, /usr/bin, /usr/sbin, /usr/lib, /usr/share

/usr/src : 시스템 실행파일/리눅스 커널 소스코드 보관, 사용자가 직접 작성한건 보관 x

/usr/include : 시스템/커널 헤더파일 보관

/usr/share : 서로 다른 아키텍처에서도 사용가능한(공유가능한) 파일들 존재 ex) man, info 같은 다큐먼트

   -> /usr/share/man 

/usr/local : /usr는 배포판이 관리, /usr/local은 시스템 관리자(사용자) 본인이 관리

/var : 자주 바뀌는거 ex) 로그, 프로세스ID

/etc : 시스템 설정 파일

/dev : 디바이스 파일

/proc : 프로세스 파일 시스템에 의해 프로세스가 파일로 표현됨

/sys : sysfs로 시스템 관련 정보 보관(프로세스가 /proc에 있어 그 외 정보) ex) 디바이스, 디바이스 드라이버

/boot : 리눅스 커널 vmlinuz 보관

/root : su/root의 디렉터리

/tmp, /var/tmp : 임시 파일

 

 

 

 

mkdir, rmdir 함수 API

#include <sys/stat.h>
#include <sys/types.h>

int mkdir(const char *path, mode_t mode); : path로 한 dir 만듬, mode는 권한 지정
- mkdir 에러 종류
ENONET - 상위 디렉터리가 없는경우
ENOTDIR - 상위 디렉터리가 디렉터리가아니라 파일인경우
EEXIST - 이미 존재하는경우
EPERM : 변경 권한이없는경우
#include <unistd.h>
int rmdir(const char *path);
 
 
umask
 
mode_t umask(mode_t mask); : ps의 umask를 mask로 변경, 이전의 umask 반환, 절대 실패 x
 * umask : ps 속성으로 8진수 보통 022, mode(파일,dir 권한)가 그대로 사용되지 않고 umask 적용된 결과가 사용됨.
        open(), mkdir()시 mode & ~umask한게 실제 권한으로 사용됨  
                  rwx rwx rwx
    mode     777 : 111 111 111
    umask   022 : 000 010 010

    real       755 : 111 101 101

 

 

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>

int main(int argc, char *argv[]){
    int i;

    if (argc < 2){
        fprintf(stderr, "%s : no argument\n", argv[0]);
        exit(1);
    }
    for (i=1; i < argc; i++){
        if (mkdir(argv[i], 0777) <0){
            perror(argv[i]);
            exit(1);
        }
    }
    exit(0);
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>


int main(int argc, char *argv[]){
    int i;
    if (argc < 2){
        fprintf(stderr, "%s : no arguments\n", argv[0]);
        exit(1);
    }
    for (i = 1 ; i < argc; i++){
        if (rmdir(argv[i]) < 0){
            perror(argv[i]);
            exit(1);
        }
    }
    exit(0);
}

 

 

 

 

 

 

 

+ Recent posts