17. 파일 검색
이 단원을 공부하기에 앞서 간략히 알아야 하는 명령에 대해서 정리를 하였다.
<파일 검색하는 데 사용되는 명령어>
locate :: 파일명으로 파일 위치 찾기
find :: 디렉토리 트리 내에서 파일 검색하기
<파일 검색 결과를 처리하는 데 사용되는 명령어>
xargs :: 표준 입력으로부터 인자 목록을 만들고 실행하기
touch :: 파일 시간을 변경하기, stat :: 파일이나 파일 시스템 상태 표시하기
> locate
- locate bin/zip → bin/zip 문자열이 포함된 결과를 보여줄 것이다.
- locate zip | grep bin → zip과 bin 문자열이 포함된 결과가 출력될 것이다.
*grep 명령어 : 특정 파일에서 지정한 문자열이나 정규표현식을 포함한 행을 출력해주는 명령어이다(내가 원하는 문자열이 있는 라인을 찾을 수 있다)
| 파이프를 사용하면, grep 명령어를 여러 개 사용할 수 있다.
> find
locate는 오로지 파일명에 근거하여 파일을 찾을 수 있지만, find는 다양한 속성에 근거하여 주어진 디렉토리를 검색하여 파일을 찾는다. find의 훌륭한 점은 특정조건에 부합하는 파일을 찾아낼 수 있다(조건을 상세하게 설정가능하다)
1. 파일 형식에 따른 조건 지정
- find ~ type d | wc -l → 디렉토리 검색으로 제한, 디렉토리 개수 출력
- find ~ type f | wc -l → 파일 검색으로 제한, 파일 개수 출력
2. 파일 크기, 파일명 검색 조건 지정
- find ~ -type f -name "*.JPG" -size +1M | wc -l → 와일드카드 패턴 *.JPG와 일치하며, 1MB보다 큰 파일 검색, 개수 출력
* :: test를 말한다. find의 명령어의 test는 훨씬 더 많다. 더 많은 test는 find의 man페이지를 확인하면 볼 수 있다.
* +, -, (생략) ::
+ → 지정한 파일 크기보다 큰 파일로 검색한다.
- → 지정한 파일 크기보다 작은 파일로 검색한다.
(생략) → 지정한 파일 크기와 정확히 일치하는 파일로 검색한다.
>연산자
모든 테스트들조차도 테스트 간의 논리적인 관계를 설명하기 위한 더 나은 방법이 필요할 수도 있다.
- -and :: 연산자를 기준으로 양쪽 테스트 조건이 모두 참인 경우에 검색된다. 아무런 연산자를 입력하지 않는다면 기본값으로 -and가 적용된다. 줄여서 -a로 적을 수도 있다.
- -or :: 양쪽 테스트 중 하나라도 참인 경우에 검색된다. 줄여서 -o로 적을 수도 있다.
- -not :: 연산자 다음에 나오는 테스트가 거짓인 경우에 검색된다. -!로 적을 수도 있다.
- ( ) :: 테스트와 연산자를 하나로 조합하여 표현한 내용을 하나로 그룹화할 때 사용된다. 명령어의 가독성을 높이기 위해 사용하기도 한다. 보통 백슬래쉬와 괄호와 함께 사용한다.
예를 들어서, 디렉토리 내의 모든 파일과 하위 디렉토리가 안전한 권한을 가지고 있는지 확인해야 할 경우,
→ 해당 파일들의 퍼미션인 0600으로 설정되어 있는지, 해당 디렉토리의 퍼미션이 0700으로 설정되어 있는지에 대해 확인할 필요가 있다.
→ 이를 논리연산자를 사용하여 판단할 수 있다.
- find ~ \( -type f -not -perm 0600 \) -or \( -type d -not -perm 0700 \)
잘못 설정된 파일과 디렉토리를 찾는 것인데, 왜 -and가 아닌 -or로 연결되어 있을까? find명령어가 파일과 디렉토리를 모두 탐색하면서 지정된 테스트에 대한 일치 여부를 하나하나 계산하기 때문이다.
expr1 -operator expr2_[연산자 로직]
- -operator가 -and일 경우 : expr1이 참이면, expr2가 실행한다 / expr1이 거짓이면, expr2가 실행하지 않는다.
- -operator가 -or일 경우 : expr1이 참이면, expr2는 실행하지 않는다/ expr1이 거짓이면, expr2는 실행한다.
왜 이런 로직으로 작동할까? 검색 성능을 개선하기 위해서이다.
> 액션
find명령의 결과 목록 출력은 유용하지만, 정말로 하고자 하는 것은 해당 목록에 있는 항목들을 동작하는 것이다.
액션에는 미리 정의된 액션과 사용자 지정의 액션이 있다.
미리 정의된 액션에는 -ls, -print, -delete, -quit 등이 있다.
- find ~ → 홈 디렉토리에 잇는 모든 파일 및 하위 디렉토리 목록을 보여준다. 사실 이는 -print 액션이 함축된 것이다. 별도의 액션 언급이 없으면 기본값으로 -print액션이 실행된다. (= find ~ -print)
- find ~ -type f -name '*.BAK' -delete → 사용자의 홈 디렉토리에 있는 모든 파일에 대하여 .BAK으로 끝나는 파일명을 검색하고, 해당 파일을 찾게 되면 모두 삭제된다.
- find ~ -type f -and -name '*.BAK' -and -delete → -and연산자는 언급되지 않으면 기본값으로 수행된다.
- -delete 는 find ~ type f와 -name '*.BAK'의 결과가 참인 경우에 수행된다.
- -name '*.BAK'은 find ~ -type f의 결과가 참인 경우에 수행된다.
- -type f는 항상 수행된다. -and관계에서 첫 번째 표현이기 때문이다.
사용자 지정의 액션은 임의의 명령어를 실행할 수도 있다. 대표적으로 -exec 액션을 활용한 명령이 있다.
-exec command { } ;
command자리에는 명령어의 이름이 들어가고, { }의 기호에는 현재 경로명에 대한 심볼릭 링크를 표시한다. 세미콜론은 명령어의 끝을 말해주는 구획 기호로 꼭 필요하다. 중괄호와 세미콜론은 Shell에서 특수한 의미로 사용되기 때문에 반드시 인용되거나 확장되어야 한다.
* 심볼릭 링크 :: 링크를 연결하여 원본 파일을 직접 사용하는 것과 같은 효과를 내는 링크이다. 심볼릭 링크를 따로 연결하는 방법은 타 블로그 주소를 첨부해놓겠다.
https://qjadud22.tistory.com/22
- find ~ -type f -name 'foo*' -ok ls -l '{}' ';' → 사용자 정의 액션을 대화식으로 실행하는 것도 가능하다 -ok 액션을 -exec자리 대신에 넣으면 지정된 명령을 실행하기 전, 사용자에게 확인 메시지를 뜬다. 'y'를 입력하면 출력되고, 'n'를 입력하면 출력되지 않는다.
-exec 액션을 사용하면, 일치하는 파일이 발견될때마다 지정된 명령을 매번 실행한다. 이런 반복성을 효율적으로 수행하기 위한 대안법이 2가지가 있다. 하나는 xargs라는 외부 명령어를 사용하는 것이고, 다른 하나는 find가 가진 새로운 기능을 활용하는 것이다.
위의 명령은 기존에 예제로 했던 명령이다. 이 예제는 일치하는 파일이 발견될 때마다 ls 명령을 실행한다.
여기서 ';' 대신에 + 기호를 사용한다. 그러면 원하는 명령이 한 번에 실행될 수 잇도록 검색 결과들을 인자 목록으로 묶어주는 find의 기능이 활성화된다. 결과는 동일하지만, 여기서는 ls 명령이 한 번 실행된 것이다.
xargs 명령어를 사용해도 똑같은 결과를 얻을 수 있게 된다. xargs 명령은 표준 입력으로부터 입력을 받아서 지정한 명령어를 위한 하나의 인자 목록으로 변환한다.
> touch명령어
보통 파일이 수정된 시간을 갱신하거나 설정할 때 사용하지만 파일명 인자가 존재하지 않는 파일이라면 새로운 빈 파일을 만든다.