На этот вопрос уже есть ответ:
Я хотел бы переименовать файлы в каждом подкаталоге, добавив имя подкаталога. Следуя ответу от Переименовать файлы, добавив имя их родительской папки , я попробовал:
rename 's/(.*)\//$1\/$1_/' */*
Однако для многих подкаталогов это не работает. У меня есть 13 000 подкаталогов, в каждом из которых содержится около 300 файлов. Получаю
-bash: /usr/bin/rename: Argument list too long
Я пробовал:
ls | xargs rename 's/(.*)\//$1\/$1_/' */*
find . -maxdepth 1 -type f -print0 | xargs rename 's/(.*)\//$1\/$1_/' */*
Оба выдают одну и ту же ошибку:
-bash: /usr/bin/xargs: Argument list too long
РЕДАКТИРОВАТЬ
xargs -L rename 's/(.*)\//$1\/$1_/' */*
xargs -L1 rename 's/(.*)\//$1\/$1_/' */*
Та же ошибка:
-bash: /usr/bin/xargs: Argument list too long
Как @egmont отмеченный, давая пути (*/*
) как аргумент (аргументы) xargs
является неправильным. Эта команда читает имена файлов из стандартного входа вместо аргументов, таким образом выходя xargs
без любого стандартного входа (раздел EDIT вопроса) бесполезно.
ls
и xargs
Проверьте, можете ли Вы просто ls
все рассматриваемые пути.
ls */*
Если да, можно использовать исправленную версию Вашего 2) опция:
ls */* | xargs rename -n 's/(.*)\//$1\/$1_/'
find
Если Вы получаете ошибку от ls
звоните, можно все еще использовать find
.
-exec
опция, которая работает так же к xargs
, таким образом, нам не будет нужно xargs
в этом случае вообще.ls */*
, используйте опции -mindepth 2 -maxdepth 2
.Исправленная версия 3) опции была бы:
find . -mindepth 2 -maxdepth 2 -type f -exec rename -n 's/(.*)\//$1\/$1_/' {} \;
Заполнитель аргумента вместе с завершенной точкой с запятой ({} \;
) гарантирует это rename
выполняется только для единственного файла за один раз, так же к xargs -L1
. Это предотвратит первичное размещение со слишком многими файлами сразу.
Можно проверить результат с помощью -n
опция я включал после rename
просто перечислять переименовывание его сделало бы. Для фактического запуска переименовать операции удалите -n
опция.