*.html 파일이 포함된 모든 디렉토리를 나열하고 디렉토리의 파일을 나열합니다.

*.html 파일이 포함된 모든 디렉토리를 나열하고 디렉토리의 파일을 나열합니다.

.htm케이스 완성 여부에 관계 없이 HTML 문서가 포함된 모든 디렉토리 목록을 얻고 싶습니다 .html.

나는 시도했다:

find / -type d -ls | tr -s [:blank:] | cut -d ' ' -f 11 | grep -i -e "*.htm" -e "*.html"

하지만 디렉토리만 나열됩니다. 이 디렉토리의 내용을 나열해야 하는데 방법을 모르겠습니다.

그런 다음 다음을 시도했습니다.

find / -type d -exec ls -l {} \; | tr -s [:blank:] | cut -d ' ' -f 9 | grep -i -e ".htm" -e ".html"

해당 항목을 찾았지만 해당 항목이 있는 디렉터리를 어떻게 인쇄합니까?

답변1

샘플 출력을 포함하여 몇 가지 가능한 명령은 다음과 같습니다.

가장 간단한:

$ find / -iname "*.htm*"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/x.htmx
foo/a.htm
bar/a.htm

-inameglob과 일치하는 파일 찾기를 나타내며 대소문자를 구분하지 않습니다. 문제는 glob이 *.htm*그것을 발견한다는 것입니다 htmx.

찾기를 방지하려면 htmx전역을 분할해야 합니다.

$ find / -iname "*.htm" -o -iname "*.html"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/a.htm
bar/a.htm

또는 grep을 사용하여 정규식을 사용합니다.

$ find / | grep -i "\.html*$"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/a.htm
bar/a.htm

정규식은 glob과 다릅니다. 특히 점( .)과 별표( *)는 glob과 정규식에서 매우 다른 의미를 갖습니다.

바라보다https://en.wikipedia.org/wiki/Glob_(programming)#Compared_to_regular_expressions더 많은 정보를 알고 싶습니다.

답변2

사용 zsh:

setopt extendedglob nullglob
for pathname in /**/*(/e{'[[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]'}); do
    printf '%s:\n' $pathname
    ls -l $pathname
done

.htm그러면 이름이 또는 로 끝나는 일반 파일 .html(대소문자 구분 없음)이 포함된 각 디렉토리의 경로 이름이 인쇄되고 그 뒤에 ls -l해당 디렉토리에 대한 출력이 표시됩니다.

루프는 /HTML 파일이 포함된 각 디렉터리를 통과합니다. 이는 전체 디렉터리 계층 구조의 모든 항목 /**/*과 일치하는 glob을 사용하여 이를 수행합니다 . /목록은 /디렉토리 경로 이름만 포함하도록 glob 한정자(첫 번째 대괄호의 첫 번째 문자)로 필터링되며 /, 목록은 [[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]true인 항목만 포함하도록 추가로 필터링됩니다. 이 표현식(여기서 확인 중인 디렉터리 경로 이름 중 하나)은 디렉터리에 또는 파일 이름 접미사(대소문자 구분 안 함)가 $REPLY있는 일반 파일이 하나 이상 포함된 경우 참이 됩니다..htm.html

e{...}와일드카드 패턴 부분은 아마도 더 간결하게 작성될 수 있을 것입니다.


사용 bash:

shopt -s globstar nullglob extglob nocaseglob
for pathname in /**/*/; do
    set -- "$pathname"/*.htm?(l)
    if [[ -f $1 ]]; then
        printf '%s:\n' "${pathname%/}"
        ls -l "$pathname"
    fi
done

이는 globstar쉘 옵션을 사용하여 **글로빙 모드( zsh쉘에서 기본적으로 활성화됨)를 활성화합니다. 이는 아래에서 위로 디렉터리 계층 전체의 모든 디렉터리 경로 이름을 반복 /하고 각 디렉터리에서 glob을 확장하려고 시도합니다 *.htm?(l)(관심 있는 HTML 파일과 일치함). glob의 첫 번째 발생이 일반 파일이거나 파일에 대한 심볼릭 링크인 경우 ls -l디렉터리 경로 이름과 목록이 출력됩니다.

당신이 가질 수 있다면목차.htmon 파일 이름 접미사를 사용하면 .htmlHTML 접미사가 있는 일반 파일(또는 일반 파일에 대한 심볼릭 링크)이 캡처되는지 확인하기 위해 별도의 루프에서 루프 내부 확장 일치를 테스트해야 합니다.

shopt -s globstar extglob nocaseglob
for pathname in /**/*/; do
    for match in "$pathname"/*.htm?(l); do
        if [[ -f $match ]]; then
            printf '%s:\n' "${pathname%/}"
            ls -l "$pathname"
            break
        fi
    done
done

nullglob더 이상 의존하지 않으므로 이 변형에서 셸 옵션을 제거했습니다 .


POSIX sh셸에서는 glob 에 액세스할 수 없으므로 **이를 사용 find하여 순환 디렉터리 경로 이름을 생성해야 합니다.

find / -type d -exec sh -c '
    for pathname do
        for match in "$pathname"/*.[hH][tT][mM] "$pathname"/*.[hH][tT][mM][lL] ; do
            if [ -f "$match" ]; then
                printf "%s:\n" "${pathname%/}"
                ls -l "$pathname"
                break
            fi
        done
    done' sh {} +

여기서는 포함된 스크립트에 대한 경로 이름 생성기 find역할을 하며 sh -c디렉토리의 경로 이름을 제공합니다.

스크립트 sh -c는 답변의 두 번째 변형과 거의 동일한 작업을 수행합니다 bash. 즉, 원하는 이름과 일치해야 하는 glob의 확장자를 반복하여 각 이름을 테스트하여 일반 파일(또는 이를 가리키는 심볼릭 링크)인지 확인합니다. ). 파일을 찾으면 디렉터리 경로 이름과 ls -l출력이 차례로 인쇄됩니다.

답변3

나는 사용하는 것이 좋습니다

find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n' | uniq | xargs -r -d '\n' ls -l

첫 번째 부분 은 대문자 또는 소문자(glob 패턴 사용)로 끝나는 모든 파일을 찾고 발견된 각 파일에 대한 디렉토리( )를 한 find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n'줄 에 하나씩 인쇄합니다..htm.html%h

디렉터리를 검색하는 방식 으로 인해 find하나 이상의 연속된 동일한 디렉터리가 나열되며 uniq각 유형 중 하나만 유지됩니다.

마지막으로, 디렉토리 목록을 제공하고 xargs디렉토리 없이는 명령을 실행하지 말라고 -r구분 기호는 개행 문자라고 알려줍니다 -d '\n'. 명령은 ls -l; 원하는 대로 수정하세요.

디렉터리 내용이 아닌 디렉터리 목록만 필요한 경우 다음 xargs섹션을 제거하세요.

find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n' | uniq

관련 정보