".[^.]*" 또는 ".??*" 전역 패턴을 정확히 언제 사용합니까?

".[^.]*" 또는 ".??*" 전역 패턴을 정확히 언제 사용합니까?

저는 Linux와 Linux의 명령줄 및 다음 문장을 이해하려고 노력하고 있습니다.

및 (현재 디렉터리와 상위 디렉터리) .*일치 로 인해 전역 문제가 발생할 수 있습니다 . 또는 와 같은 패턴을 사용하여 모든 도트 파일을 가져올 수 있습니다 .....[^.]*.??*와는 별개로현재 디렉터리와 상위 디렉터리입니다.

.[^.]*정확히 언제(어떤 명령에서) 또는 를 사용합니까 .??*?

답변1

이는 Forsyth 쉘(및 파생물 포함 ) 이외의 쉘에서 버그/잘못된 기능을 해결하기 위한 것입니다 zsh. 여기서 glob의 확장에는 및 (불행히도 이를 반환하는 시스템에서)가 포함됩니다 .fishpdksh.*...readdir()

이 껍질로,

chmod -R og-rwx .*

예를 들어 rwx 권한은 현재 디렉터리의 숨겨진 파일과 디렉터리뿐만 아니라 현재( .) 및 상위( ) 디렉터리 에 대해 반복적으로 제거됩니다 ...

ls .*이는 재귀적으로 작업을 수행하거나 , chown -R .*, 등과 같은 디렉토리에서 작동하는 명령에 find .*특히 나쁩니다 . 하지만 대부분의 다른 명령에는 여전히 짜증나고 이러한 명령을 포함 하고 grep -r blah .*싶은 명령이 생각나지 않습니다. 파일 목록에서 명령을 전달합니다....

rm유틸리티에 안전 장치를 추가해야 합니다.너무 많은 사람들이 걸려 넘어지기 때문에 이 버그를 수정하세요 rm -rf .*.

추가되면 모든 파일(숨겨지든 아니든)을 command( ) *에 인수로 전달하는 데에도 사용됩니다 .cmd -- .[!.]* ..?* *쉘에 따라 다른 해결 방법을 찾을 수 있습니다..

glob .[^.]*( .[!.]*Bourne/POSIX 셸에서)은 .(최소 두 문자의 파일 이름과 일치하기 때문에) 및 ..(두 번째 문자가 .일치하지 않기 때문에) 제외하지만 두 번째 glob이 필요한 [^.]파일도 제외합니다 ...foo..?*

이것들 ...디렉토리 순회를 위한 도구이며 일반 파일처럼 나열하는 것은 실수입니다. POSIX에서는 경로 구성 요소(예 open("."): , ) 에서 이해해야 stat("foo/../bar")하지만 반드시 디렉터리 항목으로 구현되거나 에 포함될 필요는 없습니다 readdir().

getdents()그럼에도 불구하고 대부분의 시스템은 여전히 ​​초기 Unices처럼 하드 링크를 구현하고 있으며 대부분의 시스템은 / 출력에서 ​​해당 항목을 위조 하지 않습니다 readdir().

의 경우 bash다른 방법은 옵션을 켜고 dotglob다음을 사용하는 것입니다.

chmod -R og-rwx [.]*

(그러나 숨겨진 파일이 아닌 경우 / 동작을 [.]*모방하는 옵션이 없으면 파일의 권한이 변경될 수 있습니다.)failglobzshfish

기록에 따르면 .숨겨진 파일로 시작하는 파일 이름은 다음과 같습니다.누군가가 건너뛰려고 했던 코딩 오류로 인해 탄생했으며 ., ..먼저. 아이러니하게도 숨겨진 파일로 작업을 수행하려고 할 때에도 동일한 문제가 발생합니다.


¹ globskipdotsbash 5.2+의 옵션 도 참조하세요

답변2

숨겨진 이름(점으로 시작)을 가진 모든 파일과 디렉터리를 다른 위치로 이동하려는 경우:

mv .[^.]* old-dot-files/

또는 모든 도트 파일이나 디렉터리의 도트 디렉터리에 대해 작업을 수행하려는 경우 언제든지 다음을 수행하세요.

for name in .[^.]*; do
   # process "$name"
done

이 패턴에서는 .??*일치하는 이름에 최소 3개의 문자가 포함되어야 하므로 .a유사한 이름은 선택되지 않습니다. .[^.]*반면에 이름 앞에 점이 두 개 있는 항목은 건너뜁니다.

일치하는 이름을 명시적으로 테스트하는 것이 더 나을 수도 있습니다.

for name in .*; do
    # expecting a regular file
    if [ -f "$name" ]; then
        # process "$name"
    fi
done

for name in .*; do
    # expecting a directory other than . and ..
    if [ -d "$name" ] && [ "$name" != '.' ] && [ "$name != '..' ]; then
        # process "$name"
    fi
done

내 경험상 모든 도트 파일이나 디렉터리의 도트 디렉터리에 대해 일부 작업을 수행하려는 경우는 거의 발생하지 않습니다.

관련 정보