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

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%)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.