파일/디렉토리 검색
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
명령을 실행하여 파일을 삭제함.
- 조건에 맞는 각 파일에 대해