Подтвердить что ты не робот

Как перемещать все файлы, включая скрытые файлы, в родительский каталог через *

Его должен быть популярным вопросом, но я не мог найти ответа.

Как переместить все файлы через *, включая скрытые файлы, в родительский каталог, например:

mv /path/subfolder/* /path/

Это переместит все файлы в родительский каталог, как ожидается, но не будет перемещать скрытые файлы. Как это сделать?

4b9b3361

Ответ 1

Вы можете найти исчерпывающий набор решений по этому вопросу в ответах UNIX и Linux на Как вы перемещаете все файлы (в том числе скрытые) из одного каталога в другой?. Он показывает решения в Bash, zsh, ksh93, standard (POSIX) sh и т.д.


Вы можете использовать эти две команды вместе:

mv /path/subfolder/* /path/   # your current approach
mv /path/subfolder/.* /path/  # this one for hidden files

Или все вместе (спасибо pfnuesel):

mv /path/subfolder/{.,}* /path/

Расширяется до:

mv /path/subfolder/* /path/subfolder/.* /path/

(пример: echo a{.,}b расширяется до a.b ab)

Примечание. Это покажет пару предупреждений:

mv: cannot move ‘/path/subfolder/.’ to /path/.’: Device or resource busy
mv: cannot remove /path/subfolder/..’: Is a directory

Просто игнорируйте их: это происходит потому, что /path/subfolder/{.,}* также расширяется до /path/subfolder/. и /path/subfolder/.., которые являются каталогом и родительским каталогом (см. Что делать. ".." означает, что в папке?).


Если вы хотите просто скопировать, вы можете использовать просто:

cp -r /path/subfolder/. /path/
#                     ^
#                     note the dot!

Это скопирует все файлы, как обычные, так и скрытые, так как /path/subfolder/. расширяется до "все из этого каталога" (Источник: Как скопировать с помощью cp для включения скрытых файлов и скрытые каталоги и их содержимое?)

Ответ 2

Это переместит все файлы в родительский каталог, как ожидается, но будет не перемещать скрытые файлы. Как это сделать?

Вы можете включить dotglob:

shopt -s dotglob               # This would cause mv below to match hidden files
mv /path/subfolder/* /path/

Чтобы отключить dotglob, вам нужно сказать:

shopt -u dotglob

Ответ 3

Я думаю, что это самый элегантный, так как он также не пытается переместить ..:

mv /source/path/{.[!.],}* /destination/path

Ответ 4

Альтернативным более простым решением является использование утилиты rsync:

rsync -vuar --delete-after path/subfolder/ path/

Преимущество заключается в том, что исходная папка (subfolder) будет удалена, а также часть команды, а при использовании примеров mv вам все равно нужно очистить свои папки, не говоря уже о дополнительной головной боли для покрытия скрытые и не скрытые файлы в одном шаблоне.

Кроме того, rsync обеспечивает поддержку копирования/перемещения файлов между удаленными устройствами и гарантирует, что файлы будут скопированы точно так, как они были первоначально (-a).

Использованный параметр -u пропускает существующие более новые файлы, -r recurse в каталоги и -v увеличит многословность.

Ответ 5

Позвольте представить вам моего друга "dotglob". Он включается и выключается независимо от того, содержит ли "*" скрытые файлы.

$ mkdir test
$ cd test
$ touch a b c .hidden .hi .den
$ ls -a
. ..  .den  .hi .hidden a b c

$ shopt -u dotglob
$ ls *
a b c
$ for i in * ; do echo I found: $i ; done
I found: a
I found: b
I found: c

$ shopt -s dotglob
$ ls *
.den  .hi .hidden a b c
$ for i in * ; do echo I found: $i ; done
I found: .den
I found: .hi
I found: .hidden
I found: a
I found: b
I found: c

По умолчанию он отключен.

$ shopt dotglob
dotglob         off

Лучше всего включить его, когда вы закончите, иначе вы будете путать вещи, которые предполагают, что он отключится.

Ответ 6

Используя команду find в сочетании с командой mv, вы можете запретить команде mv пытаться переместить каталоги (например, .. и .) и подкаталоги. Здесь один из вариантов:

find /path/subfolder -maxdepth 1 -type f -name '*' -exec mv -n {} /path \;

Есть проблемы с некоторыми другими предоставленными ответами. Например, каждый из следующих действий попытается переместить подкаталоги из исходного пути:

1) mv /path/subfolder/* /path/ ; mv /path/subfolder/.* /path/
2) mv /path/subfolder/{.,}* /path/ 
3) mv /source/path/{.[!.],}* /destination/path

Кроме того, 2) включает в себя. и.. файлы и 3) пропускает файлы типа..foobar,... barfoo и т.д.

Вы можете использовать mv /source/path/{.[!.],..?,}* /destination/path, который будет содержать файлы, пропущенные 3), но он все равно попытается переместить подкаталоги. Использование команды find с командой mv, как я опишу выше, устраняет все эти проблемы.