どのモジュールなのか調べてみます。use Test::Version
cpanから。だから私は使用しましたminicpan
それを反映しています。私の問題は、ダウンロードしたアーカイブを繰り返し、アーカイブ内のファイルをgrepする必要があることです。どうすればいいのか教えてもらえますか?アーカイブ内のどのファイルがどの行にあるのかどうかを知らせる方が良いでしょう。
(注:すべてタールボールではなく、一部はzipファイルです。)
答え1
さて、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
=archive名と$1
=searchパターンを使用)。 $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
配列を設定すると、一致する項目が名前リストに変換されます。$REPLY\#
アーカイブのディレクトリビュー。$REPLY\#/**/*.pm
.pm
アーカイブのファイルを一致させます。N
一致するものがない場合、glob修飾子はパターンを空のリストに展開します。
答え2
これはできると思います。
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
これはタールボールの位置にあまり具体的ではありません。誰かがより良い答えを与えることを願っています。
答え3
ウグレフオプションを使用して、圧縮ファイル(gz/Z/bz2/lzma/xz/lz4/zstd)とアーカイブ(cpio/tar/pax/zip)を繰り返し検索します-z
。オプションは、-z --zmax=2
圧縮ファイルと圧縮ファイルとアーカイブに含まれる圧縮ファイルとアーカイブを検索します(したがってzmax =レベル2)。
答え4
たぶん私の答えは誰かに役立つかもしれません。
#!/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