
У меня есть путь /participant/data, где все файлы находятся в каталоге data. Однако я хочу, чтобы структура каталога была /participant/data/subdirectory, с подкаталогом, содержащим все файлы. Это должно быть так, чтобы пройти конвейер.
Моя первая мысль была
mkdir /участник/данные/подкаталог/
mv /participant/data/*.* /participant/data/subdirectory/
Однако файлы не имеют расширения, поэтому использование *.* не сработает. Есть предложения, как это сделать?
решение1
Просто переместите все:
mv /participant/data/* /participant/data/subdirectory/
Он выдаст сообщение о невозможности перемещения subdirectory
в себя, но все остальное все равно переместит в этот подкаталог так, как вы и хотели.
Bash shopt -s extglob
добавляет несколько дополнительных подстановочных знаков, например, !(xy|z)
для соответствия всему, что похоже на*
кроме xy
или z
:
shopt -s extglob
mv /participant/data/!(subdir) /participant/data/subdir/
(Возможно, Zsh имеет еще более расширенные подстановочные знаки, которые могут соответствовать только файлам.)
Если у вас есть несколько подкаталогов, и вы не хотите их трогать, можно использовать такие инструменты, как find
или fd
для работы только с определенными элементами, в данном случае только с файлами:
find /participant/data -maxdepth 1 -type f -exec mv {} /participant/data/subdir/ \;
Это было бы немного эффективнее при использовании mv -t
и -exec +
:
find /participant/data -maxdepth 1 -type f -exec mv -t /participant/data/subdir {} +
Предыдущий (более медленный) пример также можно записать в виде for
цикла оболочки:
for x in /participant/data/*; do
if [[ -f $x ]]; then mv "$x" /participant/data/subdirectory/; fi
done
решение2
Вы можете использовать *
вместо , *.*
чтобы включить все файлы независимо от имени файла.
Но это также будет включать каталоги, включая subdirectory
, поэтому вам придется исключить его при перемещении файлов.
Это возможно с расширенными функциями сопоставления с образцом. Сначала их нужно включить (для текущего сеанса):
$ shopt -s extglob
Затем вы можете обратиться ко всем файлам, кроме одного, используяpath/!(excludedFile)
Реализовано в mv
:
$ mv /participant/data/!(subdirectory) /participant/data/subdirectory/
Есть еще несколько вариантов перемещения всех файлов, кроме одного:https://www.baeldung.com/linux/move-all-files-except-one
решение3
Самое простое в описанной вами ситуации:
cd /participant/data
mkdir .tempname
mv * .tmpname
mv .tmpname subdirectory
* будет соответствовать всем записям каталога, которые не скрыты, то есть всем, которые не начинаются с точки. Поскольку мы временно начали имя подкаталога с точки, оно не совпадает, и все записи в data будут перемещены. Теперь, если у вас есть некоторые записи, которые вы не хотите перемещать, например, другие подкаталоги, вам придется использовать один из более сложных методов, таких как те, что приведены в подробном ответе user1686.