본문으로 바로가기

[Linux] 리눅스 원하는 파일 찾기 - find

category OS/Linux 2021. 9. 19. 18:44

목차

     

    1. find 명령어

    [개요]
    
    # find [option...] [path...] [expression] 
    
    # find [-H] [-L] [-P] [-D debugopts] [-Olevel] [path...] [expression]
    
    # find [-H] [-L] [-P] [-Olevel] [-D help|tree|search|stat|rates|opt|exec] [path...] [expression]

    디렉터리 계층 구조에서 파일/디렉터리 찾을(find) 때 사용하는 명령어

    1.1. find 옵션

    1.1.1. OPTIONS

    일반적으로는 잘 사용하지 않으므로 자세한 내용이 필요한 경우엔 man find를 이용해서 확인해주세요.

    [OPTIONS]

     

     -P

      : Never follow symbolic links.  This is the default behaviour.  ( ... ) 생략

     -L                                       

      : Follow  symbolic links. ( ... ) 생략

     -H                    

      : Follow  symbolic links. ( ... ) 생략

     -D debugoptions

      : Print  diagnostic  information; this can be helpful to diagnose problems with why find is not doing what you want. ( ... ) 생략

    1.1.2. EXPRESSIONS

    [EXPRESSIONS]

     

     -maxdepth levels

      : 검색할 하위 디렉토리의 최대 깊이 지정합니다.

      : ex) -maxdepth 2 //지정한 디렉터리부터 두 번째 깊이까지 검색(위에서부터 지정한 깊이까지)

      : find 1/ -mindepth 2 = (1) (2) (3) (4)

     -mindepth levels

      : 검색할 하위 디렉터리의 최소 깊이 지정합니다.

      : ex) -mindepth 3 //지정한 디렉터리의 가장 최하위 디렉터리부터 세 번째 깊이까지 검색(맨 아래에서부터 지정한 깊이까지)

      : find 1/ -mindepth 2 = (1) (2) (3) (4) 

     

     [n 활용]

      +n : n보다 큰 경우 (지난 기준)
      -n : -n 미만일 경우 (지나지 않은 기준)
      n : n은 정확히 n이다.

     

     -amin n

      : 파일 접근(access) 시각을 n 기준으로 검색

      : -amin +160 // 마지막 접근 시각이 160분이 지난 파일 검색 (접근시간 > 160분)

      : -amin -160 // 마지막 접근 시각이 160분이 지나지 않은 파일 검색 (접근시간 < 160분)

     -atime n

      : 파일 접근(access) 시각(n * 24시간) 기준으로 검색

      : -atime +160 // 마지막 접근 시각이 160일(3840시간)이 지난 파일 검색 (접근시간 > 160일)

      : -atime -160 // 마지막 접근 시각이 160일(3840시간)이 지나지 않은 파일 검색 (접근시간 < 160일)

     -cmin n

      : 파일 변경 시각을 n 기준으로 검색

     -ctime n

      : 파일 변경 시각을 (n * 24시간) 기준으로 검색

     -mmin n

      : 파일 수정 시각을 n 기준으로 검색

     -mtime n

      : 파일 수정 시각을 (n * 24시간) 기준으로 검색

     

     -size n[cwbkMG]

      : 파일 크기를 지정해 검색

      `b'    for 512-byte blocks (this is the default if no suffix is used)
      `c'    for bytes
      `w'    for two-byte words
      `k'    for Kilobytes (units of 1024 bytes)
      `M'    for Megabytes (units of 1048576 bytes)
      `G'    for Gigabytes (units of 1073741824 bytes)

      : -size +30c //30byte를 넘는 파일 검색

     

     -executable

      : 실행 가능한 파일만 검색

     -group gname

      : 그룹 이름으로 검색(그룹 번호 사용 가능)

     -name pattern

      : 패턴에 해당하는 파일 검색

     -type

      : 지정한 유형에 해당하는 파일 검색

      d      directory
      p      named pipe (FIFO)
      f      regular file
      l      symbolic  link
      s      socket

     

     -user uname

      : 파일 소유자명으로 검색

     -readable

      : 읽을 수 있는 파일(읽기 권한)

     -writable

      :수정할 수 있는 파일(수정 권한)

     -exec command ;

      : 검색한 파일 결과에 대해 명령어 실행

     -ok command ;

      : -exec와 비슷한 명령어로 명령어 실행 전 실행 여부를 물어봅니다. 

     -ls

      :검색된 파일 상세 내역 출력

     -empty

      : 비어있는 디렉터리, 크기가 0인 파일 검색

     

    ★ ctime(변경 시간) mtime(수정 시간)은 같은가요?

    ctime

    : 파일이나 inode 값이 바뀐 시점
     퍼미션이나 소유주, 파일크기 등 파일 속성 값이 변경되었을 때 ctime 은 갱신됩니다.

    mtime

    : 파일의 수정시간이다. 파일의 내용이 바뀌었을 때 이 값이 경신됩니다.
      mtime이 갱신되면 ctime도 갱신된다.

     


    2. find 명령어 예제

     필자가 예제에 사용할 파일/디렉터리 구조입니다.

    # tree depth_1
    depth_1
    ├── 1.txt
    ├── cpu.sh
    ├── cpu.sh.ln -> cpu.sh
    └── depth_2
        ├── 2.txt
        └── depth_3
            ├── 3.txt
            └── depth_4
                └── 4.txt

    2.1. 현재 디렉터리 검색

    현재 디렉터리 및 하위 디렉터리를 포함해 파일, 디렉터리를 출력합니다.

    # find

    # find
    .
    ./depth_2
    ./depth_2/depth_3
    ./depth_2/depth_3/depth_4
    ./depth_2/depth_3/depth_4/4.txt
    ./depth_2/depth_3/3.txt
    ./depth_2/2.txt
    ./1.txt
    ./cpu.sh
    ./cpu.sh.ln

    2.2. 특정 디렉터리 검색

    1개의 경로의 디렉터리(하위 디렉터리 포함) 검색

    # find 경로

     

    여러 개의 경로의 디렉터리(하위 디렉터리 포함) 검색

    # find 경로 1 경로 2...

    # find test/ depth_1/
    test/
    test/stock1.txt
    test/stock2.txt
    test/test2
    test/test2/stock3.txt
    test/test2/test3
    test/test2/test3/stock4.txt
    test/ny.txt
    test/cpu.sh.ln
    test/cpu.sh
    depth_1/
    depth_1/depth_2
    depth_1/depth_2/depth_3
    depth_1/depth_2/depth_3/depth_4
    depth_1/depth_2/depth_3/depth_4/4.txt
    depth_1/depth_2/depth_3/3.txt
    depth_1/depth_2/2.txt
    depth_1/1.txt
    depth_1/cpu.sh
    depth_1/cpu.sh.ln

    2.3. 파일명, 패턴을 이용하여 검색

    # find -name 패턴

    # find ./ -name "cpu.sh"
    ./cpu.sh
    
    # find ./ -name "*.sh"
    ./cpu.sh
    
    # find ./ -name "*u*"
    ./cpu.sh
    ./cpu.sh.ln

    2.3. 파일의 크기를 지정하여 검색

    # find -size n[cwbkMG]

      `b'    for 512-byte blocks (this is the default if no suffix is used)
      `c'    for bytes
      `w'    for two-byte words
      `k'    for Kilobytes (units of 1024 bytes)
      `M'    for Megabytes (units of 1048576 bytes)
      `G'    for Gigabytes (units of 1073741824 bytes)

    # ll
    합계 4
    -rw-r--r--. 1 root root   0  3월 18  2021 1.txt
    -rwxr-xr-x. 1 root root 425  9월 19 15:57 cpu.sh
    lrwxrwxrwx. 1 root root   6  9월 19 15:57 cpu.sh.ln -> cpu.sh
    drwxr-xr-x. 3 root root  34  9월 19 15:56 depth_2
    
    크기가 425byte
    # find ./ -size 425c -ls
    2499799    4 -rwxr-xr-x   1 root     root          425  9월 19 15:57 ./cpu.sh
    
    크기가 400byte 이상
    # find ./ -size +400c -ls
    2499799    4 -rwxr-xr-x   1 root     root          425  9월 19 15:57 ./cpu.sh

    2.4. 파일의 타입을 지정하여 검색

    # find -type

      d      directory
      p      named pipe (FIFO)
      f      regular file
      l      symbolic  link
      s      socket

    # find ./ -type d
    ./
    ./depth_2
    ./depth_2/depth_3
    ./depth_2/depth_3/depth_4
    
    # find ./ -type f
    ./depth_2/depth_3/depth_4/4.txt
    ./depth_2/depth_3/3.txt
    ./depth_2/2.txt
    ./1.txt
    ./cpu.sh

    2.5. Depth 지정하여 검색

    지정한 디렉터리부터 아래로

    # find -maxdepth levels

     

    지정한 디텍토리의 최하위부터 위로

    # find -mindepth levels

    # tree depth_1
    depth_1
    ├── 1.txt
    ├── cpu.sh
    ├── cpu.sh.ln -> cpu.sh
    └── depth_2
        ├── 2.txt
        └── depth_3
            ├── 3.txt
            └── depth_4
                └── 4.txt
    
    [/depth_1 부터 /depth_2(두번째 깊이) 까지 존재하는 파일 검색]
    # find depth_1 -maxdepth 2 -type f
    depth_1/depth_2/2.txt
    depth_1/1.txt
    depth_1/cpu.sh
    
    [/depth_1의 최하위 경로(/depth_4) 부터 /depth_2(두번째 깊이) 까지 존재하는 파일 검색 ]
    # find depth_1 -mindepth 2 -type f
    depth_1/depth_2/depth_3/depth_4/4.txt
    depth_1/depth_2/depth_3/3.txt
    depth_1/depth_2/2.txt
    
    [/depth_1의 최하위 경로(/depth_4) 부터 /depth_3 까지(세번째 깊이) 존재하는 파일 검색 ]
    # find depth_1 -mindepth 3 -type f
    depth_1/depth_2/depth_3/depth_4/4.txt
    depth_1/depth_2/depth_3/3.txt

    2.6. 파일이 수정된 시간을 조건으로 검색

    파일 수정 시각을 n 기준으로 검색

    # find -mmin n

     

    파일 수정 시각을 일(n * 24시간) 기준으로 검색

    # find -mtime n

    # date
    2021. 09. 19. (일) 18:30:05 KST
    
    # touch now.txt
    # touch -t 202108181830 test.txt
    
    # stat now.txt
      File: `now.txt'
      Size: 0               Blocks: 0          IO Block: 4096   일반 빈 파일
    Device: fd00h/64768d    Inode: 2499807     Links: 1
    Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
    Context: unconfined_u:object_r:admin_home_t:s0
    Access: 2021-09-19 18:35:46.779905548 +0900
    Modify: 2021-09-19 18:37:59.022659473 +0900
    Change: 2021-09-19 18:37:59.022659473 +0900
     Birth: -
    
    # stat test.txt
      File: `test.txt'
      Size: 0               Blocks: 0          IO Block: 4096   일반 빈 파일
    Device: fd00h/64768d    Inode: 5648751     Links: 1
    Access: (0644/-rw-r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
    Context: unconfined_u:object_r:admin_home_t:s0
    Access: 2021-08-18 18:30:00.000000000 +0900
    Modify: 2021-08-18 18:30:00.000000000 +0900
    Change: 2021-09-19 18:38:27.026819137 +0900
     Birth: -
    
    [마지막 접근 시각이 30일이 지난 파일 검색]
    # find ./ -mtime +30 -ls -type f
    5648751    0 -rw-r--r--   1 root     root            0  8월 18 18:30 ./test.txt
    
    [마지막 접근 시각이 30일이 지나지 않은 파일 검색]
    # find ./ -type f -mtime -30 -ls
    2499807    0 -rw-r--r--   1 root     root            0  9월 19 18:37 ./now.txt

    2.7. 검색한 파일을 출력

    # find 경로 검색조건 -exec cat {} \;

     

    -exec cat {} \; 뜯어보기

     

    [실행시킬 명령어의 범위]

    = -exec ~~~ ; //세미콜론을 만나면 명령어가 종료됩니다.

     

    그러나 ;(세미콜론)은 명령어 세퍼레이터로써 명령어를 연속적으로 실행할 때 사용하는 의미가 있으므로

    \(escape)문자를 이용해 특별한 기능을 없애 줍니다.

    = -exec ~~~ \;  

     

    [{}의 의미]

    find 명령어로 찾은 파일을 의미합니다. 변수라고 보면 됩니다.

    # find depth_1/ -name "*.txt" -exec cat {} \;
    bye find command
    hello find command
    
    [검색 결과로 나온 파일 내용]
    # cat depth_1/1.txt
    hello find command
    # cat depth_1/depth_2/2.txt
    bye find command

    2.8. 검색한 파일을 저장

    # find 경로 검색조건 -exec cat {} > 파일명 \;

    # find depth_1/ -name "*.txt" -exec cat {} > merge.txt \;
    
    # cat merge.txt
    bye find command
    hello find command

    2.9. 검색한 파일을 수정

    # cat depth_1/1.txt
    hello find command
    
    [hello -> bye]
    # find depth_1/ -name "1.txt" -exec sed -i 's/hello/bye/g' {} \;
    
    # cat depth_1/1.txt
    bye find command