Может быть, я упускаю из виду то, о чем вы просите, но я думаю
du -sh *
делает именно то, что вы хотите. Здесь важно *
. С -s
вы получаете сводку для каждого каталога в командной строке , так что без явного каталога (неявного.
)вы просто получите сводку для всего, а не для каждого из каталоги под верхним -уровнем по отдельности.
С find
, который поддерживает предикат -mindepth
:
find. -mindepth 2 -type f -name '*.bak' | rename 's/\.bak$/.old/'
Предикат -mindepth
позволяет определить минимальную глубину поиска, при которой могут быть найдены совпадения. Нулевая глубина — это сам корневой путь поиска (.
), глубина 1 — это все, что находится непосредственно под корневым путем поиска (, например. ./somename
), а глубина 2 — это все, что непосредственно ниже (, например../somename/other
)и др.
Обратите внимание, что регистронезависимое соответствие, которое делает -iname
, не требуется, так как ваш rename
в любом случае не будет переименовывать файлы, которые имеют другие типы заглавных букв суффикса имени файла, поэтому вместо этого я изменил его на тест -name
.. Я также исправил ваш вызов rename
, чтобы файлы со строкой bak
в другом месте имени, например rebak.bak
, не переименовывались странным образом (, например. вr.old.bak
).
Я также добавил -type f
, чтобы find
учитывал только обычные файлы, т. е. не каталоги и т. д.
Для более портативного решения:
find. -mindepth 2 -type f -name '*.bak' -exec sh -c '
for pathname do
mv "$pathname" "${pathname%.bak}.old"
done' sh {} +
Это не зависит от утилиты rename
.
find. -mindepth 2 -type f -name '*.bak' -exec rename 's/\.bak$/.old/' {} +
Это вызов rename
непосредственно из find
.
Связанные:
С помощью bash
вы можете полностью пропустить find
и вместо этого выполнить
shopt -s globstar dotglob
rename 's/\.bak$/.old/'./*/**/*.bak
Шаблон подстановки **
соответствует любому количеству промежуточных подкаталогов. Этот специальный шаблон активируется опцией оболочки globstar
. Начальный ./*/
гарантирует, что мы ищем только в подкаталогах текущего каталога, а не в самом текущем каталоге.
Параметр оболочки dotglob
обеспечивает соответствие скрытых имен шаблону.
Вышеупомянутое, однако, не будет выбирать только обычные файлы (, как и ваша команда find
). Для этого используйте цикл:
shopt -s globstar dotglob
for pathname in./*/**/*.bak; do
[[ ! -f $pathname ]] && continue
rename 's/\.bak$/.old/' "$pathname"
done
Это также приведет к переименованию символических ссылок в обычные файлы.