Ich versuche herauszufinden, welche Module use Test::Version
verwenden im cpan. Also habe ich minicpan
verwendet um es zu spiegeln. Mein Problem ist, dass ich die heruntergeladenen Archive durchlaufen und die Dateien, die sich in den Archiven befinden, grep. Kann mir jemand sagen, wie ich das machen könnte? vorzugsweise auf eine Weise, die mir sagt, welche Datei im Archiv und in welcher Zeile sie steht.
(Hinweis:Es sind nicht alle Tarballs, einige sind ZIP-Dateien)
Akzeptierte Antwort:
Ok, wenden wir die Unix-Philosophie an. Was sind die Bestandteile dieser Aufgabe?
- Textsuche:Sie benötigen ein Tool zum Suchen von Text in einer Datei, wie z. B.
grep
. - Rekursiv:Sie brauchen ein Tool, um nach Dateien in einem Verzeichnisbaum zu suchen, wie zum Beispiel
find
. - Archive:Sie brauchen ein Tool, um sie zu lesen.
Die meisten Unix-Programme arbeiten mit Dateien. Um also problemlos auf Archivkomponenten zugreifen zu können, müssen Sie auf sie als Dateien zugreifen, mit anderen Worten, Sie müssen auf sie als Verzeichnisse zugreifen.
Das AVFS-Dateisystem bietet eine Ansicht des Dateisystems, in dem jede Archivdatei /path/to/foo.zip
ist als Verzeichnis ~/.avfs/path/to/foo/zip#
zugänglich . AVFS bietet schreibgeschützten Zugriff auf die gängigsten Archivdateiformate.
mountavfs
find ~/.avfs"$PWD" ( -name '*.zip' -o -name '*.tar.gz' -o -name '*.tgz' )
-exec sh -c '
find "$0#" -name "*.pm" -exec grep "$1" {} +
' {} 'Test::Version' ;
fusermount -u ~/.avfs # optional
Erläuterungen:
- Mounten Sie das AVFS-Dateisystem.
- Suchen Sie nach Archivdateien in
~/.avfs$PWD
, das ist die AVFS-Ansicht des aktuellen Verzeichnisses. - Führen Sie für jedes Archiv das angegebene Shell-Snippet aus (mit
$0
=Archivname und$1
=zu suchendes Muster). $0#
ist die Verzeichnisansicht des Archivs$0
.{}
statt{}
wird benötigt, falls der äußerefind
ersetzt{}
innerhalb von-exec ;
Argumente (einige tun es, andere nicht).- Optional:Unmounten Sie schließlich das AVFS-Dateisystem.
Oder in zsh ≥4.3:
mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e''
reply=($REPLY#/**/*.pm(.N))
'')
Erläuterungen:
~/.avfs$PWD/**/*.(tgz|tar.gz|zip)
entspricht Archiven in der AVFS-Ansicht des aktuellen Verzeichnisses und seiner Unterverzeichnisse.PATTERN(e''CODE'')
wendet CODE auf jede Übereinstimmung von PATTERN an. Der Name der übereinstimmenden Datei steht in$REPLY
. Einstellen derreply
array wandelt die Übereinstimmung in eine Liste von Namen um.$REPLY#
ist die Verzeichnisansicht des Archivs.$REPLY#/**/*.pm
stimmt mit.pm
überein Dateien im Archiv.- Das
N
glob Qualifier lässt das Muster zu einer leeren Liste expandieren, wenn es keine Übereinstimmung gibt.