Я пытаюсь собрать все файлы в текущем каталоге и все подкаталоги в один каталог. Я пытаюсь что-то вроде следующего
find -type f -exec mv {} collection/{} \;
, приведенная выше команда не будет работать, поскольку вторая {}
дает полный путь, как я могу собрать все файлы?
Удалите {}
из mv
, mv
примет его как целевой каталог, игнорируя любые родительские каталоги:
find -type f -exec mv {} collection/ \;
Вместо использования find
(который хорошо выполняет свою работу), вы также можете использовать оболочку для этой цели.
Скажем, вы хотите все файлы от $ PWD до $ DEST. Естественная попытка будет:
mv $PWD/* $DEST
Как это работает? Выражение «$ PWD / *» расширяется до имен всех файлов в этом каталоге. Эта функция оболочки называется "globbing". Последний аргумент mv
- это каталог назначения. Если у вас очень много файлов, это не сработает, потому что длина командной строки ограничена.
Но у решения есть проблема в том, что он пропускает точечные файлы - или «скрытые» файлы, файлы и каталоги, чье имя начинается с «.». Чтобы решить эту проблему, вы должны указать своей оболочке включить файлы точек при глобализации. Для этого используйте
shopt -s dotglob
при использовании bash
(и вы, вероятно, используете bash
, если вы не изменили значение по умолчанию). В этой оболочке приведенная выше команда будет работать и для файлов точек.
Кроме того, в zsh
у вас есть возможность выбрать это в каждом конкретном случае. Для этого поместите
setopt extendedglob
в свой .zshrc
. Затем вы можете использовать
mv $PWD/*(D) $DEST
для перемещения всех файлов, включая точечные файлы. («D» приводит к временному включению опции «GLOB_DOTS»).
Теперь первоначальный вопрос заключался в перемещении всех обычных файлов (не каталогов) из всех подкаталогов и их подкаталогов в один каталог. Это можно сделать с помощью zsh
:
mv $PWD/**/*(D.)
Здесь выражение **/*
заставляет глоббер рекурсивно спускаться в подкаталоги. D
означает «также выбирать точечные файлы»; .
означает «выбирать только обычные файлы, а не каталоги».