리눅스 Find 여러 항목(다중) 찾기, 그리고 지우기

2021. 12. 15. 17:00 OS/Linux

Find 명령이 생각보다 꽤 대단하다. 사실, 리눅스 명령어가 잘만 알고 있다면 정말 강력한 것들이 많다. 그도 그럴 수 밖에 없는 것이 다 손으로 처리해야 하던 시절의 산물이므로..

아무튼, 지금 껏 한가지 결과를 찾는데만 사용했는데, 어제 조금 다른 사용법을 터득했다.

예를 들어, mp3 파일과 mpc 파일을 찾고 싶다면?

기본은 다음과 같다.
find ~ -name '*.mp3'
find ~ -name '*.mpc'

~ 는 경로를 뜻한다. . 이면 현재부터 하위 디렉토리까지.
이렇게 두 번 해주면 된다!!! 그리고 나온 결과를 합쳐 보면 된다!!! (물론.. 이렇게 해도 안되는 건 아니다.)


어쨌든, 저 방식의 첫번째 문제.
mp3 는 찾아주지만, Mp3 나 mP3 등, 대소문자가 섞여있으면 찾아주질 못한다.
따라서 이렇게 바꾼다. 대소문자 구분을 하지 말라(ignore 인 듯)는 뜻.
find ~ -iname '*.mp3'

자... 하나 더?
find ~ -iname '*.mp3' > mp3.txt

이러면 결과가 mp3.txt 파일에 저장된다. 따라서, 위에 처럼 두번 명령을 수행한 후 생성된 문서파일을 합치면 된다. (만세!)

그러나.. find 에 선택할 수 있는 항목이 몇가진데, 저런 간단한 연산을 못하게 했을까?
두 개 이상 복수 조건을 주려면 이렇게 하면 된다. (-o 는 'or' 연산이다.)

find ~ -iname '*.mp3' -o -iname '*.mpc'

다음, mp3 가 아닌 파일들을 찾고 싶을 땐 어떻게 해야 하나?
not 연산자를 주면 된다.
find ~ ! -iname *.mp3

근데, 이 명령엔 문제가 하나 있다.리눅스는 파일이나 디렉토리나 같이 취급하기 때문에, 결과에 디렉토리까지 표시되는 것이다. 예를 들어, ~/aaa 디렉토리는 그 이름에 'mp3' 가 포함되지 않았으므로 위 검색 결과에 나타나게 된다.
이런 현상을 없애주려면 파일만 검색하든지, 디렉토리는 포함하지 않는다고 명시해주면 된다. (어떤 게 더 빠른지, 어떤 게 더 좋은 검색방법인지는 모르겠다.)
find ~ ! -iname *.mp3 -type f
find ~ ! -iname *.mp3 ! -type d

자세히 보면, 위 두가지 조건은 AND 연산이다. 이름이 'mp3' 로 끝나고, 형식은 '파일'일 것.(또는 디렉토리가 아닐 것)(근데, 생각해보면 -type 을 앞에 써주는 것이 더 좋을 듯 하다. 조건을 순차적으로 검색한다면, 먼저 이름을 검색하고나서 type 을 검색하는 것이 되므로, type 이 앞에 있는 게 좀 더 빠를 듯 하다.)

마지막으로, mp3 도 아니고 mpc 도 아니고, 나아가서 flac 도 아닌 '파일'을 검색하려면? (역시 이것 모두 AND 연산이다. 따라서 -o 가 들어가지 않는다.)

find ~ -type f ! -iname *.mp3 ! -iname *.mpc ! -iname *.flac

풀어보면, 파일을 찾되, 이름에 mp3 도 없고, mpc 도 없고, flac 도 없는 것만을 찾아라.. 라는 얘기가 된다.

정말 마지막으로 다소 위험한 명령.저렇게 찾은 것을 다 지워버리고 싶다면?
find ~ -type f ! -iname *.mp3 ! -iname *.mpc ! -iname *.flac -exec rm {} \;

{} 는 검색결과를 뜻한다. \; 는 정확히 왜 붙여야 하는지는 모르겠지만, 문법인 듯 하다.
** 2016.04.13 추가.
{} 는 검색결과라고 해도 맞지만, 정확하게는 find 로 찾아낸 파일의 전체경로명이다. ({} is a symbolic representation of the current pathname, and the semicolon is a required delimiter indicating the end of the command. -- citation from The Linux Command Line.)
원래 형식은 -exec command {} ; 이다. 그러나 {}(Curly Brackets; 중괄호) 와 ; 는 Escaping/Quoting 을 해 주는 것이 좋다고 하기 때문에, \{\} \; 또는 "{}" ";" 을 해주게 된 것이다.
통상적으로 {} 는 그냥 쓰고, 뒤에 세미콜론만 이스케이핑을 해준다.
여기서 command 는 실행가능한 모든 명령어다.


좀 더 정확성을 높이기 위해서 작은 따옴표를 붙여주는 것이 좋다.다음과 같이.
find ~ -type f ! -iname '*.mp3' ! -iname '*.mpc' ! -iname '*.flac' -exec rm '{}' \;

 

http://egloos.zum.com/nemonein/v/4753063