Распакуйте список файлов из bash ключей ассоциативных массивов - PullRequest
1 голос
/ 19 января 2020
Скрипт

My bash создает ассоциативный массив с файлами в качестве ключей.

declare -A fileInFolder
for f in "${zipFolder}/"*".zip"; do
    read -r fileInFolder[$f] _ < <(md5sum "$f")
done

... code for removing some entry in fileInFolder ...

unzip -qqc "${!fileInFolder[@]}"

и unzip запретить мне caution: filename not matched: для всех, кроме первого файла.

Следующая команда работает без проблем:

unzip -qqc "${zipFolder}/"\*".zip"

Я пытаюсь использовать 7z но я не нашел способа дать более одного zip-файла в качестве входных данных (используя -ai option для этого нужен список файлов, разделенных новой строкой , если мое понимание верно ... )

Ответы [ 2 ]

1 голос
/ 19 января 2020
  • Игнорирование причины, по которой ассоциативный массив хранит MD5 zip-файлов.
  • Как указала @Enrico Maria De Angelis, unzip принимает только один аргумент zip-файла на вызов. Поэтому вы не можете развернуть индексы имен файлов ассоциативных массивов в аргументы для одного вызова unzip.

Я предлагаю следующее решение:

#!/usr/bin/env bash

# You don't want to unzip the pattern name if none match
shopt -s nullglob

declare -A fileInFolder
for f in "${zipFolder}/"*".zip"; do
    # Store MD5 of zip file into assoc array fileInFolder
    # key: zip file name
    # value: md5sum of zip file
    read -r fileInFolder["$f"] < <(md5sum "$f")
    # Unzip file content to stdout
    unzip -qqc "$f"
done | {
 # Stream the for loop's stdout to the awk script
 awk -f script.awk
}

Альтернативная реализация, вызывающая только md5sum один раз для всех почтовых файлов

shopt -s nullglob

# Iterate the null delimited entries output from md5sum
# Reading first IFS=' ' space delimited field as sum
# and remaining of entry until null as zipname
while IFS=' ' read -r -d '' sum zipname; do
  # In case md5sum file patterns has no match
  # It will return the md5sum of stdin with file name -
  # If so, break out of the while
  [ "$zipname" = '-' ] && break
  fileInFolder["$zipname"]="$sum"
  # Unzip file to stdout
  unzip -qqc -- "$zipname"
done < <(md5sum --zero -- "$zipFolder/"*'.zip' </dev/null) | awk -f script.awk

1 голос
/ 19 января 2020

Предисловие

Этот ответ, который в основном сводится к , который вы не можете сделать с помощью одной unzip команды , предполагает, что вы знаете, что можете поставить unzip -qqc "$f" в for l oop вы написали в своем вопросе и по какой-то причине не хотите этого делать.

Мой ответ

Вы не получаете сообщение об ошибке все файлы; скорее вы получаете сообщение об ошибке для всех файлов из второго файла на .

Просто попробуйте следующее

unzip -qqc file1.zip file2.zip

, и вы получите ошибку

caution: filename not matched:  file2.zip

, который вы получаете.

Со страницы unzip man

SYNOPSIS
       unzip [-Z] [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]] file[.zip] [file(s) ...]  [-x xfile(s) ...] [-d exdir]```

похоже вам разрешено указывать один zip файл в командной строке.

На самом деле это не совсем так, вы можете указать больше zip файлов в командной строке, но для этого вы должны полагаться на собственный способ интерпретации unzip своей собственной командной строки; это частично имитирует оболочку, но все, что она может сделать, перечислено на странице man:

ARGUMENTS
       file[.zip]
              Path of the ZIP archive(s).  If the file specification is a wildcard, each matching file is processed in an order determined by  the
              operating system (or file system).  Only the filename can be a wildcard; the path itself cannot.  Wildcard expressions are similar to
              those supported in commonly used Unix shells (sh, ksh, csh) and may contain:

              *      matches a sequence of 0 or more characters

              ?      matches exactly 1 character

              [...]  matches any single character found inside the brackets; ranges are specified by a beginning character, a hyphen, and an ending
                     character.   If an exclamation point or a caret (`!' or `^') follows the left bracket, then the range of characters within the
                     brackets is complemented (that is, anything except the characters inside the brackets is considered a match).   To specify  a
                     verbatim left bracket, the three-character sequence ``[[]'' has to be used.

              (Be  sure to quote any character that might otherwise be interpreted or modified by the operating system, particularly under Unix and
              VMS.)  If no matches are found, the specification is assumed to be a literal filename; and if that also fails, the suffix .zip is ap‐
              pended.   Note that self-extracting ZIP files are supported, as with any other ZIP archive; just specify the .exe suffix (if any) ex‐
              plicitly. ```

Таким образом, вы технически столкнулись с той же проблемой, с которой вы столкнулись с 7z.

...