use Test::Version
cpan의 어떤 모듈을 찾으려고합니다 . 그래서 나는 minicpan
그것을 미러링하는 데 사용 했습니다. 내 문제는 다운로드 된 아카이브를 반복하고 아카이브에있는 파일을 grep해야한다는 것입니다. 아무도 내가 어떻게 할 수 있는지 말해 줄 수 있습니까? 바람직하게는 아카이브의 어떤 파일과 어떤 줄에 있는지 알려줍니다.
(참고 : 일부 zip 파일이 아닌 일부는 zip 파일입니다)
use Test::Version
cpan의 어떤 모듈을 찾으려고합니다 . 그래서 나는 minicpan
그것을 미러링하는 데 사용 했습니다. 내 문제는 다운로드 된 아카이브를 반복하고 아카이브에있는 파일을 grep해야한다는 것입니다. 아무도 내가 어떻게 할 수 있는지 말해 줄 수 있습니까? 바람직하게는 아카이브의 어떤 파일과 어떤 줄에 있는지 알려줍니다.
(참고 : 일부 zip 파일이 아닌 일부는 zip 파일입니다)
답변:
좋아, 유닉스 철학을 적용하자. 이 작업의 구성 요소는 무엇입니까?
grep
.find
.대부분의 유닉스 프로그램은 파일에서 작동합니다. 따라서 아카이브 구성 요소에서 쉽게 작동하려면 파일로 액세스해야합니다. 다시 말해 디렉토리로 액세스해야합니다.
에서 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
에서 현재 아카이브 의 AVFS보기 인 아카이브 파일을 찾으십시오 .$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
일치가없는 경우 패턴을 만드는 규정 글로브 빈 목록을 확장합니다.~/.avfs
)이 있으며 각 아카이브에 대한 액세스는 자동입니다 ( ~/.avfs/path/to/archive.zip\#
마운트 지점이 아닌 AVFS 파일 시스템의 일반 디렉토리 임). 물론, 액세스하는 각 아카이브는 약간의 성능 저하를 의미하지만 문제의 본질입니다.
find: missing argument to
-exec '를 얻었 기 때문이다. 그리고 zsh로부터 이것의 많은zsh: Input/output error: Data-Maker-0.27
이런 식으로 할 수있는 것 같습니다
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
타르볼의 위치에 따라 다르지 않습니다. 잘하면 누군가가 더 나은 대답을 얻을 수 있기를 바랍니다.
도전 해 주셔서 감사합니다.
#!/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
tar (child): conform.tar.gz: Cannot open: No such file or directory tar (child): Error is not recoverable: exiting now tar: Child returned status 2 tar: Error is not recoverable: exiting now
어쩌면 내 대답은 누군가에게 도움이 될 것입니다.
#!/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