У меня есть папка с около 20K файлов. Файлы названы в соответствии с шаблоном xy_{\d1,5}_{\d4}\.abc
, например xy_12345_1234.abc
. Я хотел сжать первые 10K из них с помощью этой команды:
ls | sort -n -k1.4,1.9 | head -n10000 | xargs tar -czf xy_0_10000.tar.gz
однако полученный файл содержал только около 2K файлов.
ls | sort -n -k1.4,1.9 | head -n10000 | wc -l
однако возвращает 10000, как и ожидалось.
Мне кажется, что я здесь неправильно что-то понимаю ...
Я использую zsh 5.0.2 на Linux Mint 17.1, GNU tar 1.27.1
РЕДАКТИРОВАТЬ:
разветвление в соответствии с предложением @Archemar звучит очень правдоподобно, с последним форком, перезаписывающим полученный файл - файл содержит «хвост» файлов - от 7773 до 9999 .
результат xargs --show-limit
:
Your environment variables take up 3973 bytes
POSIX upper limit on argument length (this system): 2091131
POSIX smallest allowable upper limit on argument length (all systems): 4096
Maximum length of command we could actually use: 2087158
Size of command buffer we are actually using: 131072
замена -c
с -r
или -u
не работает в моем случае. Сообщение об ошибке былоtar: Cannot update compressed archives
использование обоих -r
и -u
недопустимо и терпит неудачу сtar: You may not specify more than one '-Acdtrux', '--delete' or '--test-label' option
замена -c
на, -a
кажется, также недействительна и терпит неудачу с тем же самым, tar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
хотя я не признаю проблему azf
и Acdtrux
кажется мне несвязной.
РЕДАКТИРОВАТЬ 2:
-Т выглядит неплохо, я также нашел пример здесь .
Однако, когда я пытаюсь
ls | sort -n -k1.4,1.9 | head -n10000 | tar -czf xy_0_10000.tar.gz -T -
я получил
tar: option requires an argument -- 'T'
ну, возможно, имена файлов не доходят до tar? Но похоже, что они делают, потому что, когда я выполняю
ls | sort -n -k1.4,1.9 | head -n10000 | tar --null -czf xy_0_10000.tar.gz -T -
я получил
tar: xy_0_.ab\nxy_1_...<the rest of filenames separated by literal \n>...998.ab
Cannot stat: File name too long
Так почему tar не видит имена файлов?
ls
find
, у которого есть-print0
возможность использовать нулевой байт в качестве разделителя вместо новой строки.sort
может справиться с этим с-z
флагом.head
К сожалению, не обрабатывает понимать нулевые байтовые разделители, но этот ответ имеет решение использоватьtr
для замены\n
и\0
до и послеhead
.tar
должен--null -T -
читать имена файлов с нулевым разделителемstdin
.Ответы:
вы достигли предела xargs?
пытаться :
.tgz
файлtar czf xy_0_10000.tar.gz /hello/world
-czf
на-Azf
когда xarg достигнет своего предела, он выполнит команду fork, поэтому команда, которую вы запустили ультимативно, была
как и каждый предыдущий смола, вы можете получить только последний
tar c
запуск.Редактировать:
1) в
соответствии сдобавление выполняется (либо)man tar
unbuntu,-a
и -r кажется эквивалентным,-A, --catenate, --concatenate
2)
zip
(неgzip
) можно использовать для добавления файла, возможно, вариант gzip поможет. (используйте| xargs zip -qr xy_0_0000.zip
, это приведет к zip-файлу, а не к .tar.gz)3) использовать решение @ rsanchez.
Важно правильно добавить опцию в tar, попробуйте
где -
-T -
означает использовать опцию-T
и использовать в-
качестве аргумента-T
(вы могли бы создать список файлов/tmp/foo.lst
, затем использовать-T /tmp/foo.lst
)источник
a (add)
для добавления файлов в файл tar. Затем вы можете открыть tar и удалить папку (используя 7zip или что-то еще)touch xy_0_10000.tar.gz && { _the full command here_ ; }
.gz
файл.-r
добавление, но-a
автоматическое сжатие, которое не эквивалентно. И-rz
не работает:zip
может добавить к существующему архиву, потому что каталог не сжимается, аtar
при сжатии сжимает метаданные вместе с данными. Вы можете поtar -r
кусочкам в несжатый архив и затем сжать результат. Или ...Там нет необходимости
xargs
. Если вы сразу даетеtar
в-T -
опции он будет читать имена файлов из стандартного ввода.Например:
источник
...| tar Tczf xy_...
,...| tar Tcz -f xy_...
...| tar -czf xy_... -T
и несколько других перестановок, но я получаю толькоtar: You must specify one of the '-Acdtrux', '--delete' or '--test-label' options
,tar: -f: Cannot stat: No such file or directory
если используется-f
отдельно от других вариантов иtar: option requires an argument -- 'T'
. Не могли бы вы добавить пример использования?-T -
в концеtar
списка опций не работал, но ваш пример сработал. К сожалению, мой вопрос фактически состоял из двух частей - источника ошибки и возможного улучшения. В то время как вы справились с последним, Archemar преуспел в первом и почти имел право последнего. Я не уверен, какой из ваших ответов принять, поскольку они оба, очевидно, были полезны.Я хочу дополнить два других ответа решением zsh , которое не разбирает ls и не нуждается в xargs . Однако сейчас я не уверен, страдает ли это также от ограничения длины командной строки.
Определите функцию, которая генерирует нужный ключ сортировки путем изменения
$REPLY
.Это эквивалентно вашему
sort -n -k1.4,1.9
Создайте массив
$files
с именами файлов, отсортированными с помощью вышеуказанной функции:Это эквивалентно
ls | sort -n -k1.4,1.9
Верните первые 10 000 файлов с
Это эквивалентно
ls | sort -n -k1.4,1.9 | head -n10000
Итак, все это должно сделать свое дело:
источник