Я пытаюсь выяснить, какие модули use Test::Versionв cpan. Так что я привык minicpanотражать это. Моя проблема заключается в том, что мне нужно перебирать загружаемые архивы и выполнять поиск файлов в архивах. Может кто-нибудь сказать мне, как я мог бы сделать это? желательно таким образом, чтобы указать, какой файл в архиве и в какой строке он находится.
(примечание: они не все tarballs, некоторые из них являются zip-файлами)
Хорошо, давайте применим философию Unix. Каковы компоненты этой задачи?
Поиск текста: вам нужен инструмент для поиска текста в файле, например grep.
Рекурсивно: вам нужен инструмент для поиска файлов в дереве каталогов, например find.
Архивы: вам нужен инструмент для их чтения.
Большинство unix-программ работают с файлами. Таким образом, чтобы легко работать с компонентами архива, вам нужно обращаться к ним как к файлам, другими словами, вам нужно обращаться к ним как к каталогам.
В АВФ файловая система представляет собой вид файловой системы , где каждый архивный файл /path/to/foo.zipдоступен как каталог ~/.avfs/path/to/foo/zip#. AVFS обеспечивает доступ только для чтения к большинству распространенных форматов архивных файлов.
~/.avfs$PWD/**/*.(tgz|tar.gz|zip) соответствует архивам в представлении AVFS текущего каталога и его подкаталогов.
PATTERN(e\''CODE'\')применяет код для каждого совпадения PATTERN. Имя соответствующего файла находится в $REPLY. Установка replyмассива превращает совпадение в список имен.
$REPLY\# это каталог просмотра архива.
$REPLY\#/**/*.pm Спички .pm файлы в архиве.
Спецификатор Nglob расширяет шаблон до пустого списка, если совпадений нет.
это создает другую интересную проблему необходимости монтировать и затем размонтировать все архивы, так как часть проблемы заключается в том, что есть 22k архивов, которые необходимо найти
xenoterracide
@xenoterracide: Как это проблема? С AVFS у вас есть одна точка монтирования ( ~/.avfs), и доступ к каждому архиву происходит автоматически ( ~/.avfs/path/to/archive.zip\#это обычный каталог в файловой системе AVFS, а не точка монтирования). Конечно, каждый доступ к архиву означает небольшое снижение производительности, но это неотъемлемая часть проблемы.
Жиль "ТАК - перестань быть злым"
@Gilles только тот факт, что теперь мне нужно пройти и выяснить, как их сначала монтировать, что кажется немного плохой идеей, лучше монтировать их, когда я иду, и демонтировать после поиска.
ксенотеррацид
@xenoterracide: Опять же: нет, вам не нужно монтировать их отдельно. Полный рабочий процесс (кроме установки AVFS, если необходимо) приведен в моих фрагментах кода.
Жиль "ТАК - перестань быть злым"
@ gilles ну, мне придется немного покопаться в этом ... потому что я получаю find: missing argument to -exec'` и многое из этого из zshzsh: Input/output error: Data-Maker-0.27
xenoterracide
0
Похоже, я могу сделать это так
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
Только что увидел ваше требование номера строки. Это, вероятно, может работать с некоторой комбинацией grep -n и awk для захвата номера строки. Не может быть так просто, как grep -H, чтобы вывести список имен файлов, так как это всегда stdin, поэтому может потребоваться больше строк.
Кайл Смит
ошибки при запуске в моей системе бесконечно повторяются: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
xenoterracide
также я не осознавал, когда впервые опубликовал это, что некоторые архивы на cpan являются zip-файлами.
ксенотеррацид
Хм, я протестировал со структурой только файлов .tar.gz - можно было бы сделать более надежным выполнение соответствующих действий в зависимости от типа файла, но это должно дать достойную отправную точку.
Кайл Смит
0
Может быть, мой ответ будет полезным для кого-то:
#!/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
Вам не нужно использовать lsперед первым каналом, какой бы список сжатые файлы не работали. Только финал lessпокажет ПУТЬ жизни листета внутри сжатого архива, но не имя этого.
~/.avfs
), и доступ к каждому архиву происходит автоматически (~/.avfs/path/to/archive.zip\#
это обычный каталог в файловой системе AVFS, а не точка монтирования). Конечно, каждый доступ к архиву означает небольшое снижение производительности, но это неотъемлемая часть проблемы.find: missing argument to
-exec'` и многое из этого из zshzsh: Input/output error: Data-Maker-0.27
Похоже, я могу сделать это так
Тем не менее, это дает такие результаты:
что не очень конкретно, где в tarball. Надеюсь, кто-то может придумать лучший ответ.
источник
Спасибо за вызов, я придумал:
источник
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
Может быть, мой ответ будет полезным для кого-то:
источник
После установки
p7zip-*
вы можете сделать это:Вам не нужно использовать
ls
перед первым каналом, какой бы список сжатые файлы не работали. Только финалless
покажет ПУТЬ жизни листета внутри сжатого архива, но не имя этого.источник
Используйте find для поиска всех необходимых файлов, а zgrep - для просмотра сжатых файлов:
Не проверял это на tarballs, хотя
источник