UNIX распаковывает содержимое в несколько папок

У меня есть файл tar.gz размером около 13 ГБ. Он содержит около 1,2 млн документов. Когда я распаковываю это, все эти файлы находятся в одном каталоге, и любое чтение из этого каталога занимает целую вечность. Есть ли способ разделить файлы из tar на несколько новых папок?

например: я хотел бы создать новые папки с именем [1,2,...], каждая из которых имеет 1000 файлов.


person Srikar Appalaraju    schedule 29.08.2010    source источник
comment
Ты имеешь в виду со сценарием или как?   -  person Federico klez Culloca    schedule 29.08.2010


Ответы (5)


Это быстрое и грязное решение, но оно работает в Bash без использования каких-либо временных файлов.

i=0                                 # file counter
dir=0                               # folder name counter
mkdir $dir                          
tar -tzvf YOURFILE.tar.gz |
cut -d ' ' -f12 |                   # get the filenames contained in the archive
while read filename
    do 
        i=$((i+1))
        if [ $i == 1000 ]           # new folder for every 1000 files
        then
            i=0                     # reset the file counter
            dir=$((dir+1))
            mkdir $dir
        fi
        tar -C $dir -xvzf YOURFILE.tar.gz $filename
    done

То же, что и один лайнер:

i=0; dir=0; mkdir $dir; tar -tzvf YOURFILE.tar.gz | cut -d ' ' -f12 | while read filename; do i=$((i+1)); if [ $i == 1000 ]; then i=0; dir=$((dir+1)); mkdir $dir; fi; tar -C $dir -xvzf YOURFILE.tar.gz $filename; done

В зависимости от настроек вашей оболочки часть «cut -d ' ' -f12» для извлечения последнего столбца (имени файла) вывода содержимого tar может вызвать проблему, и вам придется ее изменить.

Он работал с 1000 файлами, но если у вас в архиве 1,2 миллиона документов, рассмотрите возможность сначала протестировать это с чем-то меньшим.

person lecodesportif    schedule 29.08.2010
comment
Спасибо всем. Решение «lecodesportif» было более готовым для моих нужд! - person Srikar Appalaraju; 30.08.2010

  • Получить список имен файлов с --list
  • Сделать файлы, содержащие имена файлов, с помощью grep
  • распаковать только эти файлы с помощью --files-from

Таким образом:

tar --list archive.tar > allfiles.txt
grep '^1' allfiles.txt > files1.txt
tar -xvf archive.tar --files-from=files1.txt
person Sjoerd    schedule 29.08.2010

Если у вас есть GNU tar, вы можете использовать опции --checkpoint и --checkpoint-action. Я не проверял это, но я думаю что-то вроде:

# UNTESTED
cd /base/dir
mkdir  $(printf "dir%04d\n" {1..1500})  # probably more than you need
ln -s dest0 linkname
tar -C linkname ... --checkpoint=1000 \
        --checkpoint-action='sleep=1' \
        --checkpoint-action='exec=ln -snf dest%u linkname ...
person Dennis Williamson    schedule 29.08.2010

вы можете посмотреть справочную страницу и посмотреть, есть ли такие варианты. в худшем случае, просто извлеките нужные файлы (возможно, используя --exclude ) и поместите их в свои папки.

person ghostdog74    schedule 29.08.2010
comment
Я не смог найти вариант в man tar, который бы удовлетворял вышеуказанным потребностям... Также, как было сказано выше, существует 1,2 миллиона файлов, и мне нужен автоматический способ создания новой папки для каждой 1000 файлов без изменений. - person Srikar Appalaraju; 29.08.2010

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

Можете ли вы изменить исходный каталог, чтобы создать там желаемую структуру, а затем смолить дерево? Если нет, вы можете распаковать файлы в том виде, в котором они находятся в файле, а затем обработать этот каталог с помощью сценария, чтобы переместить файлы в желаемое расположение. Учитывая количество файлов, это займет некоторое время, но, по крайней мере, это можно сделать в фоновом режиме.

person sizzzzlerz    schedule 29.08.2010