LINUX.ORG.RU

Скрипт замены файла в zip архивах

 , ,


1

1

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

find /home/arhives -name «*.zip» (unzip file->temp, replace file_to_file, zip file, del_temp)

Недавно начал осваивать ubuntu, в bash незнаю почти ничего.



Последнее исправление: Devill (всего исправлений: 1)

Файлами в ZIP архивах можно манипулировать без полной перепаковки. Не факт, что проще в конкретном случае, но следует иметь в виду.

Elyas ★★★★★
()
Ответ на: комментарий от Elyas

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

Devill
() автор топика
Последнее исправление: Devill (всего исправлений: 2)
Ответ на: комментарий от Devill

Думаешь именно в этом дело? Если сппрсишь препода, он скажет, что дело в том, что надо было слушать лекции.

Anoxemian ★★★★★
()

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

GLOBTMP=/tmp/UNZIP
NEWZIPS=/tmp/NEWZIPS
mkdir $GLOBTMP $NEWZIPS

for ZIP in $(find -type f -iname '*.zip'); do
  LOCTMP=$GLOBTMP/$(date +%s)
  mkdir $LOCTMP
  unzip "$ZIP" -d $LOCTMP
  find $LOCTMP -type f -iname 'file_name' -exec mv /path/to/new/file '{}' \;
  zip $NEWZIPS/$(basename "$ZIP") *
done

Пишу с кофеварки. Скрипт не проверял.

anonymous
()
Ответ на: комментарий от anonymous

Тут забыл

  zip $NEWZIPS/$(basename "$ZIP") $LOCTMP/*
anonymous
()

Задачу стоит разделить - один скрипт пусть заменяет файл в архиве, а другой пусть находит архивы и натравливает на них первый скрипт.

update_file_in_zip.sh

#!/bin/sh
if [ $# -ne 2 ] ; then
       echo "Usage: $0 <zipfile> <new file>" >&2
       exit 1
fi
ZIP=$(readlink -f "$1")
FILE=$2
NAME=$(basename "$FILE")
ZIPPATH=$(zip -sf -u "$ZIP" | awk -F/ -v FILE="$NAME" '{sub(/^  /,"")} $NF==FILE')
ZIPDIR=$(dirname "$ZIPPATH")
TMP=$(mktemp -d)
mkdir -p "$TMP/$ZIPDIR"
cp "$FILE" "$TMP/$ZIPDIR/"
cd "$TMP"
zip "$ZIP" "$ZIPDIR/$NAME"
rm -r "$TMP"

Здесь мы не распаковывая архив находим в нём нужный файл и запоминаем путь. Затем во временнойй директории воссоздаём путь, кладём уже новый файл и заставляем зип заменить только его (остальной архив не перепаковывается).

и второй скрипт уже попроще:

find /home/arhives -name "*.zip" -exec ./update_file_in_zip.sh {} файл_на_замену.txt \;
legolegs ★★★★★
()
Ответ на: комментарий от legolegs

Большое спасибо всем, особенно legolegs, Ваш скрипт сработал отлично, без доработок.

(точку только добавил в find, иначе «no such file or directory»)

find ./home/arhives -name "*.zip"
Devill
() автор топика
Последнее исправление: Devill (всего исправлений: 3)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.