Jak rekurencyjnie przeglądać skompresowane archiwa?
16
Próbuję dowiedzieć się, jakie moduły use Test::Versionw cpan. Więc zwykłem minicpanto odzwierciedlać. Mój problem polega na tym, że muszę iterować pobrane archiwa i przeglądać pliki znajdujące się w archiwach. Czy ktoś może mi powiedzieć, jak to zrobić? najlepiej w sposób, który mówi mi, który plik w archiwum i jaką linię ma.
(uwaga: nie wszystkie są archiwami, niektóre są plikami zip)
Ok, zastosujmy filozofię unix. Jakie są składniki tego zadania?
Wyszukiwanie tekstu: potrzebujesz narzędzia do wyszukiwania tekstu w pliku, takiego jak grep.
Rekurencyjne: potrzebujesz narzędzia do szukania plików w drzewie katalogów, takich jak find.
Archiwa: potrzebujesz narzędzia do ich odczytu.
Większość programów uniksowych działa na plikach. Aby więc łatwo obsługiwać komponenty archiwalne, musisz uzyskać do nich dostęp jako pliki, innymi słowy, musisz uzyskać do nich dostęp jako katalogi.
System plików AVFS przedstawia widok systemu plików, w którym każdy plik archiwum /path/to/foo.zipjest dostępny jako katalog ~/.avfs/path/to/foo/zip#. System AVFS zapewnia dostęp tylko do odczytu do najpopularniejszych formatów plików archiwów.
~/.avfs$PWD/**/*.(tgz|tar.gz|zip) dopasowuje archiwa w widoku AVFS bieżącego katalogu i jego podkatalogów.
PATTERN(e\''CODE'\')stosuje KOD do każdego dopasowania WZORU. Nazwa dopasowanego pliku znajduje się w $REPLY. Ustawienie replytablicy zmienia dopasowanie w listę nazw.
$REPLY\# to widok katalogu archiwum.
$REPLY\#/**/*.pmdopasowuje .pmpliki w archiwum.
NGlob kwalifikator sprawia, że wzór poszerzyć do pustej listy, jeśli nie ma odpowiednika.
stwarza to kolejny interesujący problem z koniecznością montowania, a następnie odmontowywania wszystkich archiwów, ponieważ część problemu polega na tym, że istnieją 22 tys. archiwów, które należy przeszukać
xenoterracide
@xenoterracide: Jak to problem? W systemie AVFS masz jeden punkt podłączenia ( ~/.avfs), a dostęp do każdego archiwum jest automatyczny ( ~/.avfs/path/to/archive.zip\#jest to zwykły katalog w systemie plików AVFS, a nie punkt podłączenia). Oczywiście każde archiwum, do którego uzyskujesz dostęp, oznacza niewielki spadek wydajności, ale jest to nieodłączny problem.
Gilles „SO - przestań być zły”
@Gilles tylko fakt, że teraz muszę przejść i wymyślić, jak je najpierw zamontować, co wydaje się trochę złym pomysłem, lepiej montować je podczas i odmontowywać po przeszukaniu.
ksenoterrakid
@xenoterracide: Ponownie: nie, nie trzeba montować ich indywidualnie. Pełny przepływ pracy (oprócz instalowania systemu AVFS w razie potrzeby) znajduje się w moich fragmentach kodu.
Gilles „SO- przestań być zły”
@Gilles no cóż, będę musiał się trochę w to find: missing argument to zagłębić ... bo dostaję -exec''i dużo tego od zshzsh: Input/output error: Data-Maker-0.27
ksenoterracyd
0
Wygląda na to, że mogę to zrobić w ten sposób
find authors/ -type f -exec zgrep "Test::Version" '{}' +
#!/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
Właśnie zobaczyłem wymagania dotyczące numeru linii. To prawdopodobnie działa z pewną kombinacją grep -n i awk, aby przechwycić numer linii. Nie może być tak proste jak grep -H, aby wyświetlić nazwę pliku, ponieważ zawsze jest to standardowe, więc może wymagać więcej linii.
Kyle Smith
błędy 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
wystąpiły
również nie zdawałem sobie sprawy, kiedy po raz pierwszy to opublikowałem, że niektóre archiwa na cpan to pliki zip.
ksenoterrakid
Hm, testowałem ze strukturą tylko plików .tar.gz - może być bardziej niezawodny, aby podejmować odpowiednie działania w zależności od typu pliku, ale to powinno dać dobry punkt wyjścia.
Kyle Smith
0
Może moja odpowiedź będzie dla kogoś pomocna:
#!/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
Nie musisz używać lsprzed pierwszym potokiem, bez względu na listę skompresowane pliki będą działać. Ostateczne lesstylko pokaże ŚCIEŻKĘ życia listet w skompresowanym archiwum, ale nie nazwa tego.
~/.avfs
), a dostęp do każdego archiwum jest automatyczny (~/.avfs/path/to/archive.zip\#
jest to zwykły katalog w systemie plików AVFS, a nie punkt podłączenia). Oczywiście każde archiwum, do którego uzyskujesz dostęp, oznacza niewielki spadek wydajności, ale jest to nieodłączny problem.find: missing argument to
zagłębić ... bo dostaję -exec''i dużo tego od zshzsh: Input/output error: Data-Maker-0.27
Wygląda na to, że mogę to zrobić w ten sposób
Daje to jednak wyniki takie jak:
co nie jest bardzo specyficzne dla tego, gdzie w tarball. Mam nadzieję, że ktoś wymyśli lepszą odpowiedź.
źródło
Dzięki za wyzwanie wymyśliłem:
źródło
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
Może moja odpowiedź będzie dla kogoś pomocna:
źródło
Po instalacji
p7zip-*
możesz to zrobić:Nie musisz używać
ls
przed pierwszym potokiem, bez względu na listę skompresowane pliki będą działać. Ostateczneless
tylko pokaże ŚCIEŻKĘ życia listet w skompresowanym archiwum, ale nie nazwa tego.źródło
Użyj find, aby zlokalizować wszystkie niezbędne pliki, a następnie zgrep, aby przejrzeć skompresowane pliki:
Nie przetestowałem tego jednak na tarballach
źródło