
.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
-iname
glob과 일치하는 파일 찾기를 나타내며 대소문자를 구분하지 않습니다. 문제는 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
디렉터리 경로 이름과 목록이 출력됩니다.
당신이 가질 수 있다면목차.htm
on 파일 이름 접미사를 사용하면 .html
HTML 접미사가 있는 일반 파일(또는 일반 파일에 대한 심볼릭 링크)이 캡처되는지 확인하기 위해 별도의 루프에서 루프 내부 확장 일치를 테스트해야 합니다.
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