1

Is it possible to skip existing files when adding files to existing archive with zip command?

zip -u adds only changed or new files, but I need to add only new files, skipping 'changed'.

Background (although it should be irrelevant): I have zip archive produced by other process, and I want to add default files, if they are missing (do not override changed files with defaults).

1 Answer 1

0

Extracting filenames from a zip archive is tricky, so use the following with caution; it will only handle filenames that contain no spaces or tabs (no characters from $IFS).

The first method uses a loop with grep to ask, for each requested file, whether it already exists in the archive; if not, the loop adds that file to the archive.

The second method runs one zip command, but tells zip to exclude files that are already in the archive, using the -x option.

zipaddgrep() {
  ziparchive=$1
  shift
  for arg
  do
    if ! zipinfo -1 "$ziparchive" | grep -Fqx "$arg"
    then
        zip "$ziparchive" "$arg"
    fi
  done
}

zipaddexclude() {
  ziparchive=$1
  shift
  zip -u "$ziparchive" "$@" -x $(zipinfo -1 "$ziparchive")
}

As a demonstration:

# setup
mkdir ~/tmp/472017
cd ~/tmp/472017
mkdir thefiles
date > thefiles/file1
date > thefiles/file2
date > thefiles/file3
zip zipfile thefiles/file{1,2}

# method 1
$ set -x
$ zipaddgrep zipfile.zip thefiles/*
+ zipaddgrep zipfile.zip thefiles/file1 thefiles/file2 thefiles/file3
+ ziparchive=zipfile.zip
+ shift
+ for arg in '"$@"'
+ grep --color=auto -Fqx thefiles/file1
+ zipinfo -1 zipfile.zip
+ for arg in '"$@"'
+ grep --color=auto -Fqx thefiles/file2
+ zipinfo -1 zipfile.zip
+ for arg in '"$@"'
+ grep --color=auto -Fqx thefiles/file3
+ zipinfo -1 zipfile.zip
+ zip zipfile.zip thefiles/file3
  adding: thefiles/file3 (stored 0%)

# cleanup
rm zipfile.zip
zip zipfile thefiles/file{1,2}

# method 2
$ zipaddexclude zipfile.zip thefiles/*
+ zipaddexclude zipfile.zip thefiles/file1 thefiles/file2 thefiles/file3
+ ziparchive=zipfile.zip
+ shift
++ zipinfo -1 zipfile.zip
+ zip -u zipfile.zip thefiles/file1 thefiles/file2 thefiles/file3 -x thefiles/file1 thefiles/file2
  adding: thefiles/file3 (stored 0%)

You must log in to answer this question.