LINUX.ORG.RU

История изменений

Исправление CrX, (текущая версия) :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.

Хотя можно и получая список до распаковки, конечно, только работать всё же подряд с одним файлом, чтоб кэш ФС как надо работал. Как-то так:

#!/bin/sh
for i in *.zip; do
    if [ "$(unzip -qql "$i" 2> /dev/null | wc -l)" -gt 1 ]; then
        dirname="$(basename "$i" .zip)"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        # FIXME: что делать, если в двух однофайловых архивах имя файла одинаковое?
        unzip "$i"
    fi
done

Тут, в принципе, если HDD, то вся скорость упрётся в I/O в любом случае, как сам скрипт написан, будет влиять на уровне погрешности. На SSD можно воспользоваться parallel вместо цикла — должно быть быстрее по идее. Не уверен, впрочем, насколько.

На HDD можно ускорить это дело, читая последовательно не по алфавиту, а по физическому расположению с помощью fastwalk:

#!/bin/sh
fastwalk | grep '.zip' | while read -r i; do
    if [ "$(unzip -qql "$i" 2> /dev/null | wc -l)" -gt 1 ]; then
        dirname="$(basename "$i" .zip)"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        # FIXME: что делать, если в двух однофайловых архивах имя файла одинаковое?
        unzip "$i"
    fi
done

По идее, так должно быть быстрее

Исправление CrX, :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.

Хотя можно и получая список до распаковки, конечно, только работать всё же подряд с одним файлом, чтоб кэш ФС как надо работал. Как-то так:

#!/bin/sh
for i in *.zip; do
    if [ "$(unzip -qql "$i" 2> /dev/null | wc -l)" -gt 1 ]; then
        dirname="$(basename "$i" .zip)"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        # FIXME: что делать, если в двух однофайловых архивах имя файла одинаковое?
        unzip "$i"
    fi
done

Тут, в принципе, если HDD, то вся скорость упрётся в I/O в любом случае, как сам скрипт написан, будет влиять на уровне погрешности. На SSD можно воспользоваться parallel вместо цикла — должно быть быстрее по идее. Не уверен, впрочем, насколько.

Исправление CrX, :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.

Хотя можно и получая список до распаковки, конечно, только работать всё же подряд с одним файлом, чтоб кэш ФС как надо работал. Как-то так:

#!/bin/sh
for i in *.zip; do
    if [ "$(unzip -qql "$i" 2> /dev/null | wc -l)" -gt 1 ]; then
        dirname="$(basename "$i" .zip)"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        # FIXME: что делать, если в двух однофайловых архивах имя файла одинаковое?
        unzip "$i"
    fi
done

Исправление CrX, :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.

Хотя можно и получая список до распаковки, конечно, только работать всё же подряд с одним файлом, чтоб кэш ФС как надо работал. Как-то так:

#!/bin/sh
for i in *.zip; do
    if [ "$(unzip -qql "$i" 2> /dev/null | wc -l)" -gt 1 ]; then
        dirname="$(basename "$i" .zip)"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        unzip "$i"
    fi
done

Исправление CrX, :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.

Хотя можно и получая список до распаковки, конечно, только работать всё же подряд с одним файлом, чтоб кэш ФС как надо работал. Как-то так:

#!/bin/sh
for i in *.zip; do
    if [ $(unzip -qql "$i" 2> /dev/null | wc -l) -gt 1 ]; then
        dirname="$(basename "$i" .zip)"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        unzip "$i"
    fi
done

Исправление CrX, :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.

Хотя можно и получая список до распаковки, конечно, только работать всё же подряд с одним файлом, чтоб кэш ФС как надо работал. Как-то так:

#!/bin/sh
for i in *.zip; do
    if [ $(unzip -qql "$i" 2> /dev/null | wc -l) -gt 1 ]; then
        dirname="${i%.*}"
        mkdir -p "$dirname"
        unzip "$i" -d "$dirname"
    else
        unzip "$i"
    fi
done

Исходная версия CrX, :

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

Я бы в таком случае никаких списков не получал. Распаковываешь в отдельный каталог, делаешь ls | wc -l на него, и если ровно один файл, переносишь куда надо, а каталог rmdir. Будет намного быстрее, чем два раза к 1666 файлам обращаться.