Profile picture

[Linux] find 명령어 정리

JaehyoJJAng2023년 03월 15일

파일/디렉토리 검색

find 명령어는 리눅스에서 파일 및 디렉토리를 검색할 떄 자주 사용되는 명령어다

$ find [경로] [옵션] [표현식]

find 표현식 정리

표현식 의미
-name 주어진 이름의 파일이나 디렉토리를 찾음
ex) find . -name "*.txt" : 현재 디렉토리 이하의 모든 디렉토리에서 .txt로 끝나는 파일 및 디렉토리 검색
-user 지정한 사용자의 파일이나 디렉토리를 찾음
-group 지정한 그룹 소유의 파일이나 디렉토리를 찾음
-uid 지정한 UID소유의 파일이나 디렉터리를 찾는다 (아이디번호로 찾기)
-gid 지정한 UID 소유의 파일이나 디렉터리를 찾는다 (그룹번호로 찾기)
-perm 지정한 허가권 값을 갖는 파일이나 디렉토리를 찾음
ex) -perm 755 : 퍼미션 값이 755로 설정된 파일이나 디렉토리 검색
-type 지정한 파일 유형 검색
d: 디렉토리
f: 일반 파일
l: 링크 파일
-exec find로 파일을 찾고 바로 연계하여 어떠한 명령을 내릴 수 있는 옵션
결과값은 {} 기호로 표시하고 \;로 끝내야함
ex) find . -name "out.txt" -exec file {} \;
-ok -exec와 동일한 작업을 한다. 다른 점은, 명령을 실행할 때마다 실행 의사를 물어본다.
-print 검색결과를 파일의 절대경로로 표시. 디폴트 옵션이다.
-print0 -print옵션과 같은데 검색결과를 한줄로 이어서 표시.
-type 지정한 파일 유형을 찾는다. (파일만 찾고 싶을때 또는 디렉터리만 찾고 싶을 경우가 많다)
d: 디렉터리,
f: 일반 파일,
l: 링크 파일,
b: 블록 디바이스,
c: 캐릭터 디바이스,
p:파이프 디바이스,
s:소켓 파일
(주로 -type f 옵션이나 -type d 옵션을 많이 쓴다)
-empty 비어있는 파일이나 디렉토리를 검색
ex) find . -empty: 현재 디렉토리 이하에서 비어있는 파일과 디렉토리 검색
-size 파일 크기와 일치하는 파일 검색
-size +파일크기 | -size -파일크기
ex) find . -size +1M
-nouser 소유자가 없는 파일을 검색(/etc/passwd 파일에 없는 사용자의 소유자로 되어 있는 파일을 검색)
-newer file1 file2 file1 보다는 이후에 file2 보다는 이전에 생성되거나 변형된 파일들을 찾을 경우에 사용한다.
-cnewer 파일명 '파일명' 부분에 적어준 파일보다 더 최근에 수정된 파일들을 찾아준다.
-maxdepth n 0이 아닌 정수값으로 경로 깊이를 지정하여 검색을 할 경우에 사용한다. 예를들어, -maxdepth 1은 시작위치로 지정한 디렉토리만 검색하고 하위 디렉토리는 찾지 않는다.
-follow 심볼릭 링크된 디렉토리도 검색을 할 경우에 사용한다.
-ls ls -dils 형식으로 찾은 파일들의 정보를 출력할때 사용한다

find 타임스탬프

몇일이 지난 로그 파일들을 찾아 자동 삭제할 때 가장 많이 쓰이는 옵션이 바로 타임스탬프 옵션이다.

그 전에 먼저 타임스탬프에 대해 정리하고 가도록 하자.(https://jaehyojjang.dev/linux/2-linux-timestamp/)

타임스탬프 옵션

분 단위로 시간도 추가로 find 명령어에서 사용할 수 있다.

옵션 요약
-mmin 파일의 데이터가 마지막으로 수정 된 시간 (분 지정)
-mtime 파일의 데이터가 마지막으로 수정 된 날짜와 시간 (일 지정)
-amin 파일의 데이터에 마지막으로 액세스 한 날짜와 시간 (분 지정)
-atime 파일의 데이터에 마지막으로 액세스 한 날짜와 시간 (일 지정)
-cmin 파일 데이터 및 상태가 마지막으로 수정 된 시간 (분 지정)
-ctime 파일 데이터 및 상태가 마지막으로 수정 된 날짜와 시간 (일 지정)

find -mtime

특정 기간에 작성, 변경된 파일 목록을 조회하고 싶을 때 find 명령어에서 -mtime옵션은 파일명에 있는 날짜가 아니라 파일의 타임스탬프로 파일을 검색한다.

기본 사용법은 find -mtime n (일수)를 지정하는데 (n일 전 = n x 24시간전)

일수 표현을 대충 정리하자면 다음과 같다.

# 만일 현재시간이 10월 10일 이라고 가정한다면,

$ find -mtime -3 # 3일(72시간)전 ~ 현재시간 -> 10.7 ~ 10.10

$ find -mtime 3  # 4일(96시간) 전 ~ 3일(72시간)전까지 -> 10.6 ~ 10.7

$ find -mtime +3 # 4일(96시간)전보다 과거 -> ~ 10.6

명령어에서 볼수 있듯이 n이 3 이라고 해서 바로 3일전이 아니라 24시간이 추가 범위적으로 계산됨을 볼 수 있다.

이는 리눅스에서 시간을 지정해서 검색할 때는 고정된 날짜와 시간 값으로 사용할 수 없기 때문이다.

명령어를 수행하는 지금의 시간을 기준으로 타임스탬프의 24시간 단위로만 검색을 할 수 있다.

예를 들어보자면,

"2021년 1월 1일 파일을 찾아라!" 는 불가능하고,

"지금 시간을 기준으로 24시간 전에 파일을 찾아라" 로 명령을 이행해야 된다.

# 4일 전부터 2일 전까지 갱신된 파일 목록 표시
$ find . -name "*.txt" -mtime 4 -mtime +1 -print

-mtime 예제

find -mtime n (일수)에서 'n일 = n*24시간' 이다 달력상의 일수가 아니다!

  • find -mtime -2: 2일(48시간) 이내에 수정된 파일 (기준에서 현재까지가 검색 대상)
  • find -mtime 2: 3일(72시간) ~ 2일(48시간) 사이에 수정된 파일 (숫자 앞에 +, - 부호가 없으면 시간 범위가 검색 대상)
  • find -mtime +2: 3일(72시간) 보다 과거인 보다 이후에 수정된 파일 (기준에서 과거 시간 전체가 검색 대상)

💡 TIP

-mtime옵션은 -,+ 부호에 따라서 그 의미가 달라지므로 확실히 숙지해서 사용하자.


현재 시간 출력하기

$ date
2023. 06. 21. () 15:00:52 KST

현재 날짜가 06월 21일 15:00분 이므로, 06월 19일 15:00 ~ 현재 시간 사이의 파일 조회

$ find . -name "*.txt" -mtime -2 -exec sh -c "ls -lrt {}" \;

# -mtime옵션 -2: 2일(48시간) ~ 현재

현재 날짜가 06월 21일 15:00 이므로, 06월 18일 ~ 06월 19일 15:00분 사이의 파일 조회

$ find . -name "*.txt" -mtime 2 -exec sh -c "ls -lrt {}" \;

# -mtime옵션 2: 3일(72시간) ~ 2일(48시간)

현재 날짜가 06월 21일 15:00 이므로, 06월 18일 15:00분 이전의 파일 조회

$ find . -name "*.txt" -mtime +2 -exec sh -c "ls -lrt {}" \;

# -mtime옵션 +2: 과거 ~ 3일(72시간)

현재 날짜가 06월 21일 이므로, -4(06월 17일 15:00분) ~ +1(06월 20일 15:00분) 사이의 파일 조회

$ find . -name "*.txt" -mtime +1 -mtime -4 -exec sh -c "ls -lrt {}" \;

# -mtime옵션 +1: 2일(48시간) 이전에 작성, 변경된 파일 조회
# -mtime옵션 -4: 4일(96시간) 이내에 작성, 변경된 파일 조회

수정된 지 8일 이상된 모든 형식의 파일들 삭제

$ find /tmp/backup -name "*.sql" -mtime +7 -exec sh -c "sudo rm -rf {}" \; 2>/dev/null

-mmin 예제

생성 또는 수정된 지 6시간이 지난 파일 삭제

find /path/to/search -type f -mmin +360 -delete
  • /path/to/search : 파일을 검색할 디렉토리 경로입니다. 원하는 디렉토리 경로를 지정해주십시오.
  • -type f: 파일 형식을 지정합니다. 여기서는 "파일"만을 대상으로 하려면 -type f를 사용합니다.
  • -mmin +360: 수정된 시간이 6시간(360분) 이상 지난 파일을 찾습니다. + 기호는 "이상"을 의미합니다.
  • -delete: 찾은 파일을 삭제합니다.

find 실전 예제

파일명으로 찾기

  • -name

$ find . -name "*.py" -delete # 확장자 검색 후 파일 삭제

타입으로 찾기

  • -type

# 현재 경로 하위에서 디렉토리/파일인 'test' 를 검색
find . -name test -type d,f

파일 크기로 찾기

  • -empty
  • -size
옵션 단위
c 1byte 단위
b 1block 단위(1block = 512 bytes)
w 2 bytes 단위
k 1 kilobytes
M 1 metabytes
G 1 gigabytes
# 파일 크기가 1024 바이트인 파일 검색
$ find . -size 1024c

# 파일 크기가 1024 파이트를 초과하는 파일 검색
$ find . -size +1024c

# 파일 크기가 1024 바이트 미만인 파일 검색
$ find . -size -1024c

검색된 파일 추가 명령

  • -exec

{} : find 에서 찾아낸 검색 결과가 하나씩 들어가는 부분

\; : -exec 다음부분에 나와있는 명령어를 실행하라는 부분

# 검색된 파일로 압축파일 생성 (tar 명령 실행)
$ find . -name [NAME] -exec tar -xcvf [파일명] {} \;

# 모든 py 파일 검색 결과를 source-list.txt에 저장
$ find / -name "*.py" 2>/dev/null

# 검색된 파일을 특정 경로로 복사
$ find . -name "*.tar.gz" -exec cp {} /mnt/ \;

# 파일 정보 출력
$ find . -name file.test -exec sh -c "file {}" \;

🏮 TIP

구분자 +\;의 차이

-exec 옵션의 제일 끝에 구분자는 +\; 이렇게 두 가지로 나뉘어져 있는데 성능 면에서 +가 더 좋다고 한다.

이유는 \;를 마지막 구분자로 사용하면 각 파일에 대해 별도의 프로세스를 진행하게 되는데 이로 인해 RAM과 처리 시간 모두에서 페널티가 발생한다고 한다

구분자 더하기 기호(+)를 사용하면 모든 표현식의 결과가 연결되어 전체적으로 한 번만 실행되는 -exec 명령에 전달된다

find . -name '파일명' -exec tar -cvfz 파일명.tar.gz {} \;

find . -name '파일명' -exec tar -cvfz 파일명.tar.gz {} +

특정 권한 파일 검색

  • -perm
# test 디렉토리에서 권한이 664인 파일을 검색해서 삭제
$ find test -perm 664 -exec rm {} \;

xargs 연결

# 파일 권한 수정
$ find . -type f -name "*.sh" 2>/dev/null | xargs -I / chmod 700 /

# 가장 최신파일만 남기고 삭제하기
$ find "경로" -type f -name "*.jpg" -mtime -30 | sort -n | tail -n 1 | xargs -I / rm /

디렉토리 찾기 예제

  • 파일이 가장 많이 들어 있는 디렉토리 찾기

$ find . -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -n | column -t

구문 기능
-xdev 현재 장치 안에서만 검색
-type f file 형의 개체 검색
cut -d "/" 구분 문자(여기에서는 /) 사이의 텍스트 제거
-f 2 찾아낸 항목에서 두 번째 필드 선택
sort 찾아낸 항목 정렬하고 표준 출력장치(stdout)로 내보냄
uniq -c sort가 보낸 항목들의 줄 수 셈
sort -n 메시지를 숫자 순서대로 출력

not executable 찾기

실행 권한이 없는 파일들을 찾는 방법

$ find /path/to/search -type f ! -perm +x

# 또는

$ find /path/to/search -type f ! -executable

실행 권한이 없고 파일 사이즈가 1033 bytes 보다 큰 파일 찾기

$ find /path/to/search -type f ! -perm +x -size +1033c

# 또는

$ find /path/to/search -type f ! -executable -size +1033c

실행 권한이 없고 파일 사이즈가 33 bytes이고 파일 소유권자가 bandit7이고 파일 그룹이 bandit6인 파일 찾기

$ find / -user bandit7 -group bandit6 -size 33c ! -executable 2>/dev/null

텍스트로 찾기

특정 문자열(텍스트)을 가진 파일을 찾는 방법

find /경로 -type f -exec grep -l '찾을문자열' {} +
find . -type f -exec grep -l 'ch-plugin' {} +
  • /경로: 검색을 시작할 디렉토리 경로입니다. 이를 필요에 맞게 변경하세요.
  • -type f: 찾을 파일의 타입을 지정합니다. f는 일반 파일을 의미합니다.
  • -exec grep -l '찾을문자열' {} +: 찾은 파일에서 grep을 사용하여 특정 문자열을 찾습니다. -l 옵션은 찾은 파일의 이름만 출력하도록 합니다. {}는 찾은 파일의 이름을 나타내며, +는 여러 파일을 한 번에 처리하도록 합니다.

특정 파일 제외하고 삭제하기

현재 디렉토리에서 proxy-host-1_access.log, proxy-host-1_error.log 파일을 제외하고 나머지 파일을 모두 삭제하는 방법은 아래와 같다.

find . -maxdepth 1 -type f -not -name 'proxy-host-1_access.log' -not -name 'proxy-host-1_error.log' -exec rm -f {} \;

이 명령어를 설명하면 다음과 같다.

  • find .
    • 현재 디렉토리(.)에서 파일을 찾는다.
  • -maxdepth 1
    • 현재 디렉토리의 최상위 레벨에서만 검색한다.
  • -type f
    • 파일 유형이 일반 파일(f)인 것만 찾는다.
  • -not -name 'proxy-host-13_access.log'
    • 이름이 proxy-host-13_access.log인 파일을 제외함.
  • -not -name 'proxy-host-13_error.log'
    • 이름이 proxy-host-13_error.log인 파일을 제외함.
  • -exec rm -f {} \;
    • 조건에 맞는 각 파일에 대해 rm -f 명령을 실행하여 파일을 삭제함.

Loading script...