1

У меня около 300 7zip-архивов, в каждом по несколько файлов, и внутри нет структуры каталогов.

Мне нужно извлечь все эти архивы в папки, которые соответствуют соответствующему архиву.

Пример:

foo.7z
bar.7z

Извлечь содержимое foo.7z в /foo/
Извлечь содержимое bar.7z в /bar/


Я попробовал этот скрипт:

find . -name "*.7z" -type f| xargs -I {} 7z x -o{} {}

Но это привело к:

can not open output file ./foo.7z/file.bin
Skipping    file.bin

Что я делаю неправильно? Я использую Ubuntu Linux.

2 ответа2

3

Вы пытаетесь создать каталог с тем же именем, что и файл. Это не может работать: не может быть двух записей каталога с одинаковым именем.

Один из способов исправить это - использовать basename для удаления расширения .7z из файлов и создания каталогов без суффикса .7z .

Подобно:

for archive in *.7z; do 7z x -o"`basename \"$archive\" .7z`" "$archive"; done
1
for file in *.7z; do
    directory=${file/%.7z/}
    if mkdir ${directory}; then
        ( cd ${directory}; 7z x ../${file} )
    else
        echo "Unable to create directory ${directory} for archive ${file}" 1>&2
    fi
done

Для этого сначала нужно перебрать все файлы *.7z используя переменную file . Как только он захватывает имя файла, он использует манипуляции со строкой bash, чтобы .7z с конца и сделать из этого новую переменную, directory .

Затем он попытается создать каталог и, если сможет, откроет подоболочку, зайдет в этот каталог и распакует архив 7zip.

Если не удалось создать этот каталог, сообщение отправляется со стандартной ошибкой.

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

Самая сложная часть этой строки:

Каталог = $ {файл /%. 7z /}

Это вышеупомянутое манипулирование строкой bash, которое будет искать .7z в конце строки и, если присутствует, заменять ее ничем. Если бы я захотел заменить его, скажем, на .zip , я мог бы использовать ${file/%.7z/.zip} .

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .