• Unix ПОМОЖИТЕ Кто может — подскажите плз по поводу tar, du, pv, find.
    Задача в целом — нужно найти в помойке директорий файлы определенных типов по расширению и затарить/гзипить их. С этим все просто, выглядит вот так:
    tar zcf /tmp/archive.tgz -T <(find -type f -name \.c -o -name \.h -o -name \*.xsl)

    Доп. задача — хочется видеть прогресс выполнения, ибо файлов дохуя. Решается навскидку вот так:
    tar zcf — -T <(find -type f -name \.c -o -name \.h -o -name \*.xsl) | pv > /tmp/archive.tgz

    Конечная задача, которую не могу решить — видеть не только прогресс, но и временную оценку.
    pv это позволяет, только ей надо размер передать. А я блять не могу сообразить, как выщемить суммарный размер найденных файлов. Уже голову сломал :(

Replies (60)

  • @Vugluskr, ну узнать размер файлов можно так: find -type f -name \.c -o -name \.h -o -name \*.xsl | xargs du -bs | awk '{s+=$1}END{print s}' а вот как что бы find запускался только один раз, это нужно подумать
  • @ramok, отдельно размер посчитать — да, просто. Как втиснуть в одну команду — не соображу :(
  • @Vugluskr, в awk все накопить, посчитать и запускать. find -type f -name \.c -o -name \.h -o -name \*.xsl | xargs du -bs | awk '{s+=$1;n=$2" "n} END{system("tar zc "n"|pv -ns "s" > /tmp/archive.tgz")}'
  • @Vugluskr, у меня не взлетело. Ты навскидку написал, без проверки?
  • @ramok, В любом случае — спасибо большое :) Постараюсь щаз сам разрыть
  • @Vugluskr, я вот проверял core.org.ua идея простая. в переменной s накапливается сумма, в n — имена. потом в самом конце (блок END) формируется и запускается sh команда через system
  • @ramok, там конечно надо еще заморочится с именами файлов в которых могут быть пробелы. но это отдельная песня Ж:-)
  • @ramok, Идея понятна, ага. Но у меня вылетело не из-за имен :)
    awk: execute of /bin/sh failed (Argument list too long)
  • @Vugluskr, файликов реально дохуя
  • @Vugluskr, а. тогда это нужно побороть через print | команда, внутри awk
  • @ramok, Хорошо, еще раз спасибо :)
  • @Vugluskr, попробуй так | awk '{s+=$1;n=$2"\n"n} END{print n |& "tar zcT — |pv -ns "s" > /tmp/archive.tgz"}
  • @ramok, не, так ваще в приглашение выпадает :)
  • @Vugluskr, у тебя gnu awk? если нет, то вместо |& попробуй |
  • @Vugluskr, а вот кстати, поидее должно хавать любые символы в файлах: find -type f -name \.c -o -name \.h -o -name \*.xsl -print0 | xargs -0 du -bs | awk '{s+=$1;n=$2"\n"n} END{print n | "tar zcT — |pv -ns "s" > /tmp/archive.tgz"}'
  • @ramok, ну еще вместо pv -ns, сделать pv -s, и красиво будет. лады, больше не флужу Ж:-) вечно увлекаюсь. удачи
  • @ramok, Нет уж погоди :) Если есть время и желание — то я только за. Дык вот факультативные задачки:
    Не хавает любые имена, ошибка на амперсандах, пробелах и скобках в именах директорий
    Считает неправильный размер. То есть, считает-то наверное правильный, но не соответствует работе тара
  • @Vugluskr, awk у тебя какой? gnu?
  • @ramok, бубутновый стандартный, я не знаю честно говоря — гну он или нет
  • @Vugluskr, find -type f -name \.c -o -name \.h -o -name \.xsl -print0 | xargs -0 du -bs | awk '{s+=$1;sub(/^[0-9]\t/,"");n=$0"\0"n}END{printf"%s",n|"tar --null -cT-|pv -s "s"|gzip -9> /tmp/archive.tgz"}' поидее обе проблемы пофикшены
  • @ramok, 1. везде вставлена работа с NULL терминейтет строками, где работа со списками файлов 2. pv вставлен между tar и gzip, что бы отображало правильные проценты
  • @ramok, :))) Cannot stat: File name too long
    tar: Exiting with failure status due to previous errors
  • @ramok, Извините пожалста, я не специально :)
  • @Vugluskr, это полный вывод? вместо команды вставь: "tar --null -vcT-|gzip -9> /tmp/archive.tgz", и все что выведет на pastebin
  • @ramok, Не, это не полный. Перед этим куча имен файлов склеенных в одну строку.
  • @Vugluskr, ну я же не телепат
  • @ramok, Сорри, ступил. Ща
  • @Vugluskr, find -type f -name \.c -o -name \.h -o -name \.xsl -print0 | xargs -0 du -bs | awk '{s+=$1;sub(/^[0-9]\t/,"");n=$0"\0"n}END{ORS="";print n|"tar --null -cT-|pv -s "s"|gzip -9> /tmp/archive.tgz"}'
  • @ramok, Абсолютно идентичный результат. Тар берет список как имя одного файла.
  • @Vugluskr, 1. что выводит tar --version | head -1 2. посмотри man tar, если у него ключик --null 3. вместо "tar ... tgz" вставь "od -x | head -3" и покажи что выводит
  • @ramok, 1. lucky@space:/backstore_200G/java/_Current$ tar --version | head -1
    tar (GNU tar) 1.25

    2. --null
    -T reads null-terminated names, disable -C

    3. 0000000 2f2e 6954 6b63 7465 452f 676e 6e69 2f65
    0000020 6577 2f62 4557 2d42 4e49 2f46 7378 2f6c
    0000040 6968 7473 726f 2e79 7378 2e6c 542f 6369
  • @Vugluskr, пункт 3 у тебя с printf"%s",n или с print n? у меня просто не воспроизводится: core.org.ua
  • @Vugluskr, А где принтф должен быть? В твоих командах я не видел его
  • @Vugluskr, был в одном из вариантов. забуть. покажи что выводит awk --version | head -1
  • @ramok, гы :) lucky@space:/backstore_200G/java/_Current$ awk --version | head -1
    awk: not an option: --version
  • @Vugluskr, похоже у тебя nawk или mawk стоит, а я под gawk делал. попробуй поставить gawk. он должен автоматом под awk поставится. ну или проверь update-alternatives --config awk, и скажи какой у тебя был
  • @ramok, у меня mawk
  • @Vugluskr, ща, ставлю гавк
  • @Vugluskr, а я попробую на mawk сделать. похоже что "\0" не срабатывает как ожидалось
  • @ramok, Йоп, заработало :)
  • @ramok, Спасибо тебе, человечище :)
  • @Vugluskr, что бы не пропадало, опубликуй на linsovet.com. там можно не регатся. жалко если пропадёт, да и пригодится кому. кстати, если у тебя много файлов, то не плохо бы запускать показывать ожидание "генерируем список файлов"
  • @Vugluskr, find . -type f -name \.mp3 -print0 | xargs -0 du -bs | awk '{s+=$1;sub(/^[0-9]\t/,"");n=$0"\0"n;printf "scan files: %d\r",i++}END{ORS="";print n|"tar --null -cT-|pv -s "s"|gzip -9>/tmp/archive.tgz"}' вот, выводит еще "scan files: номер текущего"
  • @ramok, опубликовал
  • @ramok, Супер-пупер :) Ты крут! С меня магарыч
  • @ramok, не хочу расстраивать, но в архив попадают то ли ваще все файлы, то ли просто не те, которые нужно :)
  • @Vugluskr, чорд Ж:-) а ты там маски правильно в find указал? надо смотреть что за лишние файлы и на каком пайпе они появляются
  • @ramok, Маски правильно, абсолютно уверен. Появляются например служебные из .svn/ директорий, они ваще без разрешения.
  • @Vugluskr, йопт, без расширения
  • @Vugluskr, find -type f -name \.c -o -name \.h -o -name \*.xsl | grep svn выводит что?
  • @ramok, нене, ничо. Я первым делом проверил не файнд ли это грешит. Не он :)
  • @Vugluskr, ну проверяй после du. и если там тоже все хорошо, то проверяй в awk вставив: awk '{print $0; ...'
  • @ramok, Бляха-муха. Это уже я накосячил с генерацией аргументов для файнда :( Извини пожалста. Мой косяк — задал лишнюю "-о"
  • @Vugluskr, "Маски правильно, абсолютно уверен" Ж:-P
  • @ramok, Я ж руками пишу — все акей, выводит как надо.
    Генерирую функцию для баша — там много типов — он перед самой первой пихает -o — и все идет в разнос
  • @Vugluskr, понятно. проблема забора и столбов
  • @ramok, Окончательный вариант, который ровно то, что нужно :)
    find -type f -regex ".\.\(c\|h\|xsl\)" -print0 | xargs -0 du -bs | awk '{s+=$1;sub(/^[0-9]\t/,"");n=$0"\0"n;printf "scan files: %d\r",i++}END{ORS="";print n|"tar --null -cT-|pv -s "s"|gzip -9>/tmp/archive.tgz"}'

    find через name — таки косячил на длинных списках масок при вызове из башевской функции.