私はどんなモジュールを見つけようとしている 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$PWD
でアーカイブファイルを探します。$0
=アーカイブ名と$1
=検索するパターンを使用)。$0#
は、アーカイブ$0
のディレクトリビューです。{\}
ではなく{}
が必要なのは、{}
引数の内部のfind
が-exec ;
を置き換える場合です(一部はそうする、一部はしない)。または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
配列を設定すると、一致が名前のリストに変わります。$REPLY\#
は、アーカイブのディレクトリビューです。$REPLY\#/**/*.pm
は、アーカイブ内の.pm
ファイルに一致します。N
glob修飾子は、一致がない場合にパターンを空のリストに展開します。このようにできるようです
find authors/ -type f -exec zgrep "Test::Version" '{}' +
ただし、次のような結果になります。
authors/id/J/JO/JONASBN/Module-Info-File-0.11.tar.gz:Binary file (standard input) matches
これはtarballのどこにあるかはそれほど明確ではありません。うまくいけば、誰かがより良い答えを考え出すことができます。
Findを使用して必要なすべてのファイルを見つけ、そのzgrepを使用して圧縮ファイルを調べます。
find <folder> -type f -name "<search criteria[*gz,*bz...]>" -execdir zgrep -in "<grep expression>" '{}' ';'
ただし、これをtarballでテストしなかった
多分私の答えは誰かのために役立ちます:
#!/bin/bash
findpath=$(echo $1 | sed -r 's|(.*[^/]$)|\1/|')
# tarballs to check in
find $findpath -type f | while read tarball; do
# get list of files in tarball (not dirs ending in /):
if [ -n "$(file --mime-type $tarball | grep -e "application/jar")" ]; then
jar tf $tarball | grep -v '/$' | while read file; do
# get contents of file and look for string
grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")
if [ -n "$grepout" ]; then
echo "*** $tarball has matching file ($file):"
echo $grepout
fi
done
Elif tar -tf $tarball 2>/dev/null; then
tar -tf $tarball | grep -v '/$' | while read file; do
# get contents of file and look for string
grepout=$(unzip -q -c $tarball $file | grep $3 -e "$2")
if [ -n "$grepout" ]; then
echo "*** $tarball has matching file ($file):"
echo $grepout
fi
done
else
file=""
grepout=$(grep $3 -e "$2" $tarball)
if [ -n "$grepout" ]; then
echo "*** $tarball has matching:"
echo $grepout
fi
fi
done
挑戦をありがとう、私は思いついた:
#!/bin/bash
#
# tarballs to check in
find authors/ -type f | while read tarball; do
# get list of files in tarball (not dirs ending in /):
tar tzf $tarball | grep -v '/$' | while read file; do
# get contents of file and look for string
tar -Ozxf conform.tar.gz $file | grep -q 'Text::Version' && echo "Tar ($tarball) has matching File ($file)"
done
done
インストール後p7Zip-*
これを行うことができます:
ls | xargs -I {} 7z l {} | grep whatever | less
圧縮ファイルが機能するリストが何であれ、最初のパイプの前にls
を使用する必要はありません。最後のless
は、圧縮されたアーカイブ内のリセットライフのパスのみを表示しますが、これの名前は表示しません。