Как перемещать все файлы, включая скрытые файлы, в родительский каталог через *
Его должен быть популярным вопросом, но я не мог найти ответа.
Как переместить все файлы через *, включая скрытые файлы, в родительский каталог, например:
mv /path/subfolder/* /path/
Это переместит все файлы в родительский каталог, как ожидается, но не будет перемещать скрытые файлы. Как это сделать?
Ответы
Ответ 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
, как я опишу выше, устраняет все эти проблемы.