(Angepasst von Wie greife ich rekursiv durch komprimierte Archive? )
Installieren Sie AVFS , ein Dateisystem, das transparenten Zugriff auf Archive bietet. Führen Sie diesen Befehl zunächst einmal aus, um eine Ansicht des Dateisystems Ihres Computers einzurichten, in der Sie auf Archive zugreifen können, als wären sie Verzeichnisse:
mountavfs
Wenn /path/to/archive.zip
es sich danach um ein erkanntes Archiv handelt, ~/.avfs/path/to/archive.zip#
handelt es sich um ein Verzeichnis, das den Inhalt des Archivs zu enthalten scheint.
find ~/.avfs"$PWD" \( -name '*.7z' -o -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' \) \
-exec sh -c '
find "$0#" -name "*vacation*.jpg"
' {} 'Test::Version' \;
Erklärungen:
- Hängen Sie das AVFS-Dateisystem ein.
- Suchen Sie nach Archivdateien in
~/.avfs$PWD
der AVFS-Ansicht des aktuellen Verzeichnisses.
- Führen Sie für jedes Archiv das angegebene Shell-Snippet aus (mit
$0
= Archivname und $1
= zu durchsuchendem Muster).
$0#
ist die Verzeichnisansicht des Archivs $0
.
{\}
eher als {}
die äußeren , falls erforderlich find
Ersatz {}
innerhalb -exec ;
Argumente (einige tun es, manche nicht).
Oder in zsh ≥4.3:
mountavfs
ls -l ~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)(e\''
reply=($REPLY\#/**/*vacation*.jpg(.N))
'\')
Erklärungen:
~/.avfs$PWD/**/*.(7z|tgz|tar.gz|zip)
stimmt mit Archiven in der AVFS-Ansicht des aktuellen Verzeichnisses und seiner Unterverzeichnisse überein.
PATTERN(e\''CODE'\')
wendet CODE auf jede Übereinstimmung von MUSTER an. Der Name der übereinstimmenden Datei ist in$REPLY
. Durch das Festlegen des reply
Arrays wird die Übereinstimmung in eine Liste von Namen umgewandelt.
$REPLY\#
ist die Verzeichnisansicht des Archivs.
$REPLY\#/**/*vacation*.jpg
Streichhölzer *vacation*.jpg
Dateien im Archiv .
- Das
N
Glob-Qualifikationsmerkmal erweitert das Muster zu einer leeren Liste, wenn keine Übereinstimmung vorliegt.
Gilles 'SO - hör auf böse zu sein'
quelle
Meine übliche Lösung:
Beispiel:
Ergebnisse sind wie:
Wenn Sie nur die Zip-Datei mit Treffern möchten :
Der Dateiname wird hier zweimal verwendet, sodass Sie eine Variable verwenden können.
Mit find können Sie PATH / TO / SEARCH verwenden
quelle
Eine andere Lösung, die funktioniert, ist
zgrep
quelle
zgrep
ist das? Das funktioniert nicht mit dem mit GNUgzip
(/bin/zgrep: -r: option not supported
,zgrep (gzip) 1.6
) ausgeliefertenIMHO Benutzerfreundlichkeit sollte auch eine Sache in der Bash sein:
und für Teer (dieser ist ungetestet ...)
quelle
unzip
Implementierung kann mit 7z- oder tar.gz-Dateien umgehen?libarchive
Diebsdtar
meisten dieser Dateiformate können verarbeitet werden. Sie können also Folgendes tun:Was Sie mit GNU vereinfachen (und verbessern können, um die Groß- und Kleinschreibung nicht zu berücksichtigen)
find
mit:Der Pfad des Archivs, in dem sich diese
*vacation*jpg
Dateien befinden, wird jedoch nicht gedruckt . Um diesen Namen zu drucken, können Sie die letzte Zeile durch Folgendes ersetzen:das gibt eine Ausgabe wie:
Oder mit
zsh
:Beachten Sie, dass es eine Reihe anderer Dateiformate gibt, die nur
zip
odertgz
Dateien in Verkleidung wie.jar
oder.docx
Dateien sind. Sie können diese zu Ihremfind
/zsh
Suchmuster hinzufügen.bsdtar
ohne sich um die Erweiterung zu kümmern (wie in, es hängt nicht von der Erweiterung ab, um den Dateityp zu bestimmen).Beachten Sie, dass
*vacation*.jpg
oben auf dem vollständigen Pfad des Archivmitglieds nicht nur der Dateiname übereinstimmt,vacation.jpg
sondern auch aufvacation/2014/file.jpg
.Um nur mit dem Dateinamen übereinzustimmen , besteht ein Trick darin, den Extraktionsmodus zu verwenden . Verwenden Sie
-s
(Ersetzung), bei dem reguläre Ausdrücke mit einemp
Flag verwendet werden, um die Namen der übereinstimmenden Dateien zu drucken, und stellen Sie dann sicher, dass keine Datei extrahiert wird, wie z.Beachten Sie, dass die Liste auf stderr ausgegeben und
>>
an jede Zeile angehängt wird. In jedem Fall könnenbsdtar
, wie bei den meistentar
Implementierungen, die angezeigten Dateinamen beschädigt werden, wenn sie Zeichen wie Zeilenumbruch oder Backslash (gerendert als\n
oder\\
) enthalten.quelle