use Test::Version
を使用するモジュールを見つけようとしています cpanで。そこで、minicpan
を使用しました それをミラーリングします。私の問題は、ダウンロードされたアーカイブを反復処理し、アーカイブにあるファイルをgrepする必要があることです。誰かが私がこれを行う方法を教えてもらえますか?できれば、アーカイブ内のどのファイルとその行にあるかを教えてくれる方法で。
(注:すべてがtarballであるとは限らず、一部はzipファイルです)
承認された回答:
では、UNIX哲学を適用しましょう。このタスクのコンポーネントは何ですか?
- テキスト検索:
grep
などのファイル内のテキストを検索するためのツールが必要です 。 - 再帰的:
find
など、ディレクトリツリーでファイルを検索するためのツールが必要です。 。 - アーカイブ:アーカイブを読むにはツールが必要です。
ほとんどのUNIXプログラムはファイルを操作します。したがって、アーカイブコンポーネントを簡単に操作するには、ファイルとしてアクセスする必要があります。つまり、ディレクトリとしてアクセスする必要があります。
AVFSファイルシステムは、すべてのアーカイブファイル/path/to/foo.zip
が存在するファイルシステムのビューを表示します。 ディレクトリとしてアクセス可能~/.avfs/path/to/foo/zip#
。 AVFSは、最も一般的なアーカイブファイル形式への読み取り専用アクセスを提供します。
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
説明:
- AVFSファイルシステムをマウントします。
-
~/.avfs$PWD
でアーカイブファイルを探します 、これは現在のディレクトリのAVFSビューです。 - アーカイブごとに、指定されたシェルスニペットを実行します(
$0
を使用) =アーカイブ名と$1
=検索するパターン)。 -
$0#
アーカイブのディレクトリビューです$0
。 -
{}
{}
ではなく 外側のfind
の場合に必要です{}
を置き換えます-exec ;
内 議論(そうする人もいれば、しない人もいます)。 - オプション:最後にAVFSファイルシステムをアンマウントします。
またはzsh≥4.3の場合:
mountavfs
grep 'Test::Version' ~/.avfs$PWD/**/*.(tgz|tar.gz|zip)(e''
reply=($REPLY#/**/*.pm(.N))
'')
説明:
-
~/.avfs$PWD/**/*.(tgz|tar.gz|zip)
現在のディレクトリとそのサブディレクトリのAVFSビューのアーカイブと一致します。 -
PATTERN(e''CODE'')
PATTERNの各一致にCODEを適用します。一致したファイルの名前は$REPLY
にあります 。reply
の設定 arrayは、一致を名前のリストに変換します。 -
$REPLY#
アーカイブのディレクトリビューです。 -
$REPLY#/**/*.pm
.pm
と一致します アーカイブ内のファイル。 -
N
glob qualifierは、一致するものがない場合、パターンを空のリストに展開します。