GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann man komprimierte Archive rekursiv durchsuchen?

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ßere find 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 der reply 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.
Verwandte:Wie kann man überprüfen, auf welche Signale ein Prozess hört?
Linux
  1. So verwenden Sie den Linux-Grep-Befehl

  2. So archivieren und komprimieren Sie Dateien unter Linux

  3. Wie grep in PDF-Dateien?

  4. Wie grep ich rekursiv?

  5. Wie grep \n in Datei

So finden Sie eine Zeichenfolge in einer Datei unter Linux

So zeigen Sie den Inhalt eines Archivs oder einer komprimierten Datei unter Linux an

So verwenden Sie grep unter Linux

So entpacken Sie tar bz2 xz gz-Archive unter Linux

Wie man unter Linux rekursiv chown

Wie zeichnet man Strom in ngspice?