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

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

HTML 문서가 포함되어 있거나 대문자 또는 소문자를 무시 .htm하거나 완료한 모든 디렉토리 목록을 얻고 싶습니다 ..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과 regex에서 매우 다른 의미를 갖습니다.

보다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 한정자(첫 번째 괄호의 이니셜 )에 의해 디렉터리 경로 이름만 포함하도록 필터링되며, 추가로 목록은 true인 /항목만 포함하도록 필터링됩니다 . 검사 중인 디렉터리 경로 이름 중 하나인 [[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]이 표현식은 디렉터리에 또는 파일 이름 접미사(대소문자 구분 안 함)가 $REPLY있는 일반 파일이 하나 이상 포함된 경우 참이 됩니다 ..htm.html

e{...}Globbing 패턴의 일부는 아마도 더 간결하게 작성될 수 있습니다 .


사용 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

이는 쉘 옵션을 사용하여 globbing 패턴(셸에서 기본적으로 활성화됨 ) globstar의 사용을 활성화합니다 . 전체 디렉토리 계층 구조의 모든 디렉토리 경로 이름을 아래부터 반복하고 각 디렉토리의 glob을 확장하려고 시도합니다 (이는 우리가 관심 있는 HTML 파일과 일치합니다). 이 glob의 첫 번째 일치 항목이 일반 파일이거나 이에 대한 기호 링크인 경우 디렉터리 경로 이름과 목록이 출력됩니다.**zsh/*.htm?(l)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

관련 정보