find를 사용하여 파일 이름의 특수 문자를 처리하는 방법

find를 사용하여 파일 이름의 특수 문자를 처리하는 방법

다음과 같은 특정 문자로 시작하는 모든 파일을 찾고 싶습니다.

find . -maxdepth 1 \( -name "^m*" -a ! -name "g$" \) -print

하지만 누군가 이름에 특수 문자가 포함된 파일을 생성한다면 어떻게 될까요? 예를 들어

touch "
marst"

표준을 충족하더라도 감지되지 않습니다. 공백으로 시작하는 파일을 찾으려면 코드를 어떻게 변경해야 합니까?

또한 \( -name "^m*" -a ! -name "g$" \)find의 파일이 "marr"이 아니라 "./marr"이기 때문에 작동하지 않습니다. 이는 아무것도 찾을 수 없음을 의미합니다. 단어의 시작 부분과 일치하도록 코드를 어떻게 변경할 수 있나요?

답변1

-name항상 이름만 일치합니다. 즉, 경로와 일치하지 않습니다.모두이름. 해당 값은 정규 표현식이 아닌 패턴이므로 다음 m을 사용하여 시작하는 파일 이름을 찾을 수 있습니다.

-name 'm*'

g그리고 다음으로 끝나는 이름

-name '*g'

정규식을 사용하려면 -regex옵션을 참조하세요.

답변2

개행 문자로 시작하거나 그 뒤에 오는 파일 이름을 일치시키려면 m다음과 같습니다.

NL='
'
find . \( -name 'm*' -o -name "*${NL}m*" \) -print

적어도 GNU의 경우 find유효한 *문자 시퀀스를 형성하지 않는 바이트 시퀀스는 일치하지 않습니다. 이것이 잠재적인 문제라면 C 로케일을 사용하는 것이 더 나을 것입니다.

LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) -print

예:

$ touch mom $'two\nminutes' $'mad\x80'
$ find . -name 'm*'
./mom
$ find . \( -name 'm*' -o -name "*${NL}m*" \) -print
./two?minutes
./mom
$ LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) -print
./mad?
./two?minutes
./mom

다음 으로 시작 m하지만 끝나지 않는 줄을 포함하는 파일 이름의 경우 g:

LC_ALL=C find . \( -name 'm*' -o -name "*${NL}m*" \) ! \(
  -name '*g' -o -name "*g${NL}*" \) -print

일부 find구현에는 파일 일치에 대한 비표준 옵션이 있습니다.(보통은 그렇지 않다.이름) 정규식을 사용하지만 구현에 따라 동작이 다르므로 여기서는 필요하지 않습니다.

m예를 들어, 정규 표현식이 필요한 곳은 이름이 어떤 것으로 끝나는 줄로 시작하지 않는 파일을 찾는 것입니다 g(예: nor $'cat\nman\ndog'는 아님 ).$'plate\nmug\ncup'$'cat\nman\nmug'

GNU 사용 find:

LC_ALL=C find . -regextype posix-extended -regex \
  ".*/(([^m$NL/][^/$NL]*|m[^/$NL]*[^$NL/g]|m|)($NL|\$))*"

m또는 이름이 다음과 같이 시작하고 끝나지 않는 줄이 하나 이상 있는 파일 g( 과 유사 $'mad\nmug'하지만 아님 $'ming\nmong'):

LC_ALL=C find . -regextype posix-extended -regex \
  ".*/([^/]*$NL)?m([^$NL/]*[^g$NL/])?(\$|${NL}[^/]*)"

답변3

-regex플래그를 사용하여 glob에서 제공하는 더 복잡한 일치가 필요한지 확인할 수 있습니다. 전체 경로와 일치하므로 파일 이름 부분만 일치시키려면 다음과 같이 할 수 있습니다.

find . -maxdepth 1 -regex '/[ 
]?m[^/]*[^g]$' -print

참고하시기 바랍니다이 답변개행 문자를 일치시키는 데 사용할 수 없으므로 \n요청했기 때문에 문자 클래스에 공백이 있는 개행 문자를 넣습니다.

답변4

^find에서는 the 또는 the를 $단순한 이름으로 사용할 필요가 없습니다 .
용도 찾기모델이름을 위해. 패턴은 다음과 같습니다.

  • 전체 이름과 일치합니다. 처음부터 끝까지. 언제나.
  • find는 이 패턴을 사용하기 전에 찾은 모든 파일의 경로를 제거합니다.
  • 유일한 특수 문자는 * ?and [ ](^ 또는 $ 아님)입니다.

m따라서 및로 시작하는 파일을 일치시키려면아니요다음으로 끝납니다 g:

 find . -maxdepth 1 -name 'm*[!g]' -o -name 'm'

'm'파일에 문자가 하나만 있는 경우를 다룹니다 .

그러나 생성한 파일 touch $'\nmarst'(예, bash에서와 같이 개행을 작성할 수 있습니다)은 new-line 으로 시작하지 않고 mnew-line 으로 시작합니다 $'\n'. 단순 모드에서는 대체할 수 있는 방법이 없지만 -ofind의 OR( ) 옵션을 사용할 수 있습니다.

find . -maxdepth 1 \( -name 'm*' -o -name $'\n'"m*" \) -a ! -name '*g'

요구사항이 길어지면 이는 어려워집니다.
매우 복잡한 문자열의 경우 -regexfind 옵션을 사용할 수 있습니다.

관련 정보