История изменений
Исправление 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 файлам обращаться.