Задача Ant unzip и извлечение файлов только из другого каталога

У меня есть zip-файл и отдельно каталог, содержащий некоторые файлы. Из zip-файла я хотел бы извлечь только те файлы, которые существуют в каталоге (выполняя преобразование имени файла для файлов по мере их извлечения ... в основном, я делаю резервные копии этих файлов).

Нет проблем сделать что-то подобное с ‹copy›, в котором есть набор файлов с элементом ‹present›, но, похоже, это не работает для меня с unzip:

<unzip src="${cur.srcdir.live}" dest="${cur.srcdir.archive-files.dir}" overwrite="true">
    <fileset dir=".">
        <present present="both" targetdir="${cur.srcdir}" />
        <type type="file" />
    </fileset>
    <globmapper from="*" to="*.${backup.suffix}" />
</unzip>

Кто-нибудь делал что-то подобное раньше? Это Ant 1.8.0. Спасибо!


person FanOfTamago    schedule 18.10.2011    source источник
comment
Похоже, что задача распаковки не поддерживает такие выражения, как вы публикуете. Возможно, вам следует распаковать архив во временную папку, а затем скопировать файлы в режиме обновления (с помощью текущего состояния) в папку назначения   -  person Alex K    schedule 18.10.2011
comment
Оцените эту мысль. В крайнем случае я полностью распакую архив, но поскольку иногда эти архивы бывают большими (и просто ради элегантности в целом), я надеялся избежать этого.   -  person FanOfTamago    schedule 18.10.2011
comment
Я понимаю. Я добавил в закладки ваш вопрос. Может быть, вам стоит запустить unzip как команду с параметром -f (обновить существующие файлы)? Я имею в виду, что вы можете использовать exec задачу: ant.apache.org/manual/Tasks/exec .html   -  person Alex K    schedule 18.10.2011


Ответы (3)


Я смог решить свою проблему, «подделав» селектор ‹present›, который можно использовать в ‹copy›. Вот как:

Сначала я использовал pathconvert, чтобы создать список файлов в моей папке:

    <pathconvert property="extract.list" pathsep="&#xA;">
        <path>
            <fileset dir="${extract.src.dir}" includes="${extract.src.dir.relpath}">
                <type type="file" />
            </fileset>
        </path>
        <map from="${extract.src.dir}\" to="" />
    </pathconvert>

Обратите внимание на то, что для пользователя карты в списке указываются относительные пути, а не абсолютные пути. Кроме того, разделитель - это новая строка.

Затем этот список записывается в файл:

    <echo file="${props.tmp.file}" message="~~~~noop~~~~&#xA;${extract.list}" append="false" />

Я поместил туда запись "nooop", чтобы в файле всегда была хотя бы одна строка. Это важно, потому что на следующем шаге мы будем использовать это как включаемый файл. Если файл include пуст, Ant интерпретирует это как «разрешить что угодно» ... но мы хотим убедиться, что пустой список не приведет к извлечению из zip-архива ничего.

Последний шаг - извлечь из zip-архива, используя наш временный файл сверху в качестве включаемого файла. Globmapper переименовывает файлы при извлечении с соответствующими именами резервных копий:

    <unzip src="${extract.archive}" dest="${extract.dest.dir}" overwrite="true">
        <patternset>
            <includesfile name="${props.tmp.file}" />
        </patternset>
        <globmapper from="*" to="*.${backup.suffix}" />
    </unzip>
person FanOfTamago    schedule 19.10.2011

Вы можете попробовать вызвать команду unzip через задачу exec.
Образец, который Я проверил в Windows, что обновляет только измененные файлы в dest.folder:

<property name="zip.file_name" value="Archive.zip"/>
<property name="src.folder" value="d:\"/>
<property name="dest.folder" value="d:\55"/>

<target name="unzip">
    <echo>unzip -fo ${src.folder}${zip.file_name}</echo>
    <exec dir="${dest.folder}" executable="cmd.exe" output="${src.folder}operation_result.txt">

        <arg line="/c unzip -fo ${src.folder}${zip.file_name}"/>
    </exec>
</target>

Если вы хотите сохранить исходные файлы, вы можете использовать эту команду:

<arg line="/c unzip -foB ${src.folder}${zip.file_name}"/>

В случае использования параметра -B ваши исходные файлы (хранящиеся в папке) будут переименованы - будет добавлен символ тильды. Вы получаете два набора файлов - извлеченные из архива и старые оригинальные файлы.
После этого вы можете переименовывать файлы с помощью задачи move.

person Alex K    schedule 18.10.2011
comment
Проблема в том, что я не хочу обновлять существующие файлы. Я хочу извлечь соответствующие файлы для резервного копирования. Итак, предположим, что zip-файл содержит A, B и C. Теперь предположим, что мой исходный каталог (вне zip) содержит A и C. Я хочу извлечь A и C из zip-файла в файлы A.backup и C.backup. . Из моего вопроса видно, что у меня есть globmapper для этой цели, и этот метод отлично работает с наборами файлов в целом. Если вы видите способ сделать это с помощью exec и процесса распаковки, дайте мне знать! - person FanOfTamago; 18.10.2011
comment
Спасибо; Я понимаю, о чем вы говорите, но выбрал другой подход, чтобы избежать использования exec. Смотрите другой ответ. Тем не менее, я ценю ваш мозговой штурм по этому поводу со мной! - person FanOfTamago; 19.10.2011

Добавьте это здесь на случай, если кому-то понадобится изменить структуру каталогов при извлечении. Я так много пытался заставить это работать. Задача Ant Unzip принимает cutdirsmapper.

<unzip dest="${build.dir}/packages">
    <fileset dir="${src.dir}/packages" includes="*.pkg" />
    <!-- Exctract build folder contents also moving one level up. -->       
    <cutdirsmapper dirs="1" />
    <patternset>
        <include name="build/" />
    </patternset>
</unzip>
person igor    schedule 07.01.2014
comment
Думаю, это лучшее решение. Оно работает! Однако вы могли бы объяснить этот атрибут dirs, указать, сколько вложенных dirs будет удалено из результата. - person Pavoletto; 23.05.2019