Ich möchte die Liste aller Verzeichnisse erhalten, die HTML-Dokumente enthalten, vollständig .htm
oder .html
ohne Berücksichtigung der Groß- und Kleinschreibung.
Ich habe versucht:
find / -type d -ls | tr -s [:blank:] | cut -d ' ' -f 11 | grep -i -e "*.htm" -e "*.html"
Es werden jedoch nur Verzeichnisse aufgelistet, und ich muss den Inhalt dieser Verzeichnisse auflisten und weiß nicht wie.
Ich habe dann versucht:
find / -type d -exec ls -l {} \; | tr -s [:blank:] | cut -d ' ' -f 9 | grep -i -e ".htm" -e ".html"
Und es findet sie, aber wie drucke ich die Verzeichnisse aus, in denen sie sich befinden?
Antwort1
Hier sind einige mögliche Befehle einschließlich Beispielausgabe
Das Einfachste:
$ find / -iname "*.htm*"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/x.htmx
foo/a.htm
bar/a.htm
-iname
bedeutet, Dateien zu finden, die mit glob übereinstimmen, und dabei nicht zwischen Groß- und Kleinschreibung zu unterscheiden. Das Problem ist, dass der glob *.htm*
auch findet htmx
.
Um das Finden zu verhindern, htmx
müssen Sie den Glob aufteilen:
$ find / -iname "*.htm" -o -iname "*.html"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/a.htm
bar/a.htm
Oder verwenden Sie grep, das reguläre Ausdrücke verwenden kann:
$ find / | grep -i "\.html*$"
foo/a.HTM
foo/b.HTML
foo/b.html
foo/a.htm
bar/a.htm
Beachten Sie, dass Regex nicht dasselbe ist wie Glob. Insbesondere der Punkt ( .
) und der Stern ( *
) haben in Glob und Regex sehr unterschiedliche Bedeutungen.
Sehenhttps://en.wikipedia.org/wiki/Glob_(programming)#Compared_to_regular_expressionsfür mehr Informationen.
Antwort2
Verwendung von zsh
:
setopt extendedglob nullglob
for pathname in /**/*(/e{'[[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]'}); do
printf '%s:\n' $pathname
ls -l $pathname
done
Dies druckt den Pfadnamen jedes Verzeichnisses, das eine reguläre Datei enthält, deren Name mit oder endet .htm
( .html
unabhängig von der Groß-/Kleinschreibung), gefolgt von der ls -l
Ausgabe für dieses Verzeichnis.
Die Schleife durchläuft alle Verzeichnisse, in denen oder darunter /
eine HTML-Datei enthalten ist. Dies geschieht mithilfe des /**/*
Globs, der für sich genommen alles in der gesamten /
Verzeichnishierarchie abgleicht. Diese Liste wird so gefiltert, dass sie nur Verzeichnispfadnamen enthält, die durch den /
Glob-Qualifizierer (den Anfangsbuchstaben /
in der ersten Klammer) bestimmt werden, und die Liste wird weiter gefiltert, sodass sie nur die Einträge enthält, für die [[ -n $REPLY/(#i)*.htm(l#)(#q.) ]]
wahr ist. Dieser Ausdruck, wobei $REPLY
einer der untersuchten Verzeichnispfadnamen ist, ist wahr, wenn ein Verzeichnis mindestens eine reguläre Datei mit einem Dateinamensuffix oder enthält (ohne Berücksichtigung der Groß-/Kleinschreibung) .htm
..html
Der e{...}
Teil des Globbing-Musters könnte wahrscheinlich prägnanter geschrieben werden.
Verwendung von 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
Dies verwendet die globstar
Shell-Option, um die Verwendung des **
Globbing-Musters zu aktivieren (standardmäßig in der zsh
Shell aktiviert). Es durchläuft alle Verzeichnispfadnamen in der gesamten Verzeichnishierarchie von /
unten und versucht, den Glob in jedem Verzeichnis zu erweitern *.htm?(l)
(dies entspricht den HTML-Dateien, an denen wir interessiert sind). Wenn die erste Übereinstimmung dieses Globs eine normale Datei oder ein symbolischer Link zu einer solchen ist, werden der Verzeichnispfadname und die ls -l
Auflistung ausgegeben.
Wenn Sie möglicherweiseVerzeichnissemit dem Suffix .htm
„on .html
filename“ müssten Sie die Übereinstimmungen der Erweiterung innerhalb der Schleife in einer separaten Schleife testen, nur um sicherzustellen, dass Sie alle regulären Dateien (oder symbolischen Links zu regulären Dateien) mit den HTML-Suffixen erfassen:
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
Ich habe die nullglob
Shell-Option in dieser Variante gelöscht, da wir nicht mehr davon abhängig sind.
Da Sie in der POSIX- sh
Shell keinen Zugriff auf den Glob haben **
, müssen Sie find
zur Generierung der Verzeichnispfadnamen für die Schleife Folgendes verwenden:
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 {} +
Hierbei find
fungiert es als eine Art Pfadnamengenerator für das eingebettete sh -c
Skript und speist es mit Pfadnamen von Verzeichnissen.
Das sh -c
Skript macht im Wesentlichen das Gleiche wie die zweite bash
Variante der Antwort, d. h. es durchläuft die Erweiterung des Globs, die mit den gewünschten Namen übereinstimmen sollte, und prüft jeden Namen, um festzustellen, ob es sich um eine normale Datei handelt (oder um einen symbolischen Link zu einer solchen). Sobald es eine Datei findet, druckt es den Verzeichnispfadnamen, gefolgt von der ls -l
Ausgabe.
Antwort3
Ich würde vorschlagen,
find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n' | uniq | xargs -r -d '\n' ls -l
Der erste Teil, , findet alle Dateien, die mit oder in Groß- oder Kleinbuchstaben find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n'
enden (unter Verwendung von Glob-Mustern) und druckt das Verzeichnis ( ) für jede gefundene Datei, ein Verzeichnis pro Zeile..htm
.html
%h
Aufgrund der Art und Weise , wie find
Verzeichnisse gescannt werden, werden ein oder mehrere aufeinanderfolgende identische Verzeichnisse aufgelistet; uniq
von jedem wird nur eines behalten.
Schließlich geben wir die Liste der Verzeichnisse an weiter xargs
und sagen ihm, dass er keinen Befehl ohne Verzeichnisse ausführen soll -r
und dass das Trennzeichen eine neue Zeile ist -d '\n'
. Der Befehl lautet ls -l
; ändern Sie ihn nach Ihren Wünschen.
Wenn Sie nur die Liste der Verzeichnisse und nicht deren Inhalt benötigen, lassen Sie den xargs
Teil weg:
find / '(' -iname '*.htm' -o -iname '*.html' ')' -printf '%h\n' | uniq