it-swarm-ru.tech

Как вы перемещаете все файлы (включая скрытые) из одного каталога в другой?

Как переместить все файлы в каталоге (включая скрытые) в другой каталог?

Например, если у меня есть папка "Foo" с файлами ".hidden" и "notHidden" внутри, как мне переместить оба файла в каталог с именем "Bar"? Следующее не работает, так как ".hidden" файл остается в "Foo".

mv Foo/* Bar/

Попробуй сам.

mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
155
Cory Klein

Zsh

_mv Foo/*(DN) Bar/
_

или

_setopt -s glob_dots
mv Foo/*(N) Bar/
_

(Не указывайте _(N)_, если вы знаете, что каталог не пустой.)

Bash

_shopt -s dotglob nullglob
mv Foo/* Bar/
_

Ksh93

Если вы знаете, что каталог не пуст:

_FIGNORE='.?(.)'
mv Foo/* Bar/
_

Стандарт (POSIX) ш

_for x in Foo/* Foo/.[!.]* Foo/..?*; do
  if [ -e "$x" ]; then mv -- "$x" Bar/; fi
done
_

Если вы хотите, чтобы команда mv возвращала состояние ошибки, даже если оно прошло успешно, это намного проще:

_mv Foo/* Foo/.[!.]* Foo/..?* Bar/
_

GNU найти и GNU mv

_find Foo/ -mindepth 1 -maxdepth 1 -exec mv -t Bar/ -- {} +
_

Стандартная находка

Если вы не возражаете перейти на исходный каталог:

_cd Foo/ &&
find . -name . -o -exec sh -c 'mv -- "[email protected]" "$0"' ../Bar/ {} + -type d -Prune
_

Вот более подробно о контроле соответствия файлов точек в bash, ksh93 и zsh.

Bash

Установите dotglob .

_$ echo *
none zero
$ shopt -s dotglob
$ echo *
..two .one none zero
_

Также есть более гибкая GLOBIGNORE переменная , которую вы можете задать в списке символов подстановки, разделенных двоеточиями, чтобы игнорировать их. Если не установлено (настройка по умолчанию), оболочка ведет себя так, как если бы значение было пустым, если задано dotglob, и как если бы значение было _.*_, если опция не установлена. См. Расширение имени файла в руководстве. Распространяющиеся каталоги _._ и _.._ всегда опускаются, если только _._ явно не соответствует шаблону.

_$ GLOBIGNORE='n*'
$ echo *
..two .one zero
$ echo .*
..two .one
$ unset GLOBIGNORE
$ echo .*
. .. ..two .one
$ GLOBIGNORE=.:..
$ echo .*
..two .one
_

Ksh93

Установите переменную FIGNORE . Если не установлено (настройка по умолчанию), оболочка ведет себя так, как если бы значение было _.*_. Чтобы игнорировать _._ и _.._, они должны совпадать явно (в руководстве в ksh 93s + 2008-01-31 говорится, что _._ и _.._ всегда игнорируются, но это делает не правильно опишите реальное поведение).

_$ echo *
none zero
$ FIGNORE='@(.|..)'
$ echo *
..two .one none zero
$ FIGNORE='n*'
$ echo *
. .. ..two .one zero
_

Вы можете включить точечные файлы в шаблон , сопоставив их явно.

_$ unset FIGNORE
$ echo @(*|.[^.]*|..?*)
..two .one none zero
_

Чтобы раскрытие оказалось пустым, если каталог пуст, используйте параметр сопоставления с образцом N: ~(N)@(*|.[^.]*|..?*) или ~(N:*|.[^.]*|..?*).

Zsh

Установите параметр _dot_glob_ .

_% echo *
none zero
% setopt dot_glob
% echo *
..two .one none zero
_

_._ и _.._ никогда не сопоставляются, даже если шаблон явно совпадает с ведущим _._.

_% echo .*
..two .one
_

Вы можете включать точечные файлы в определенный шаблон с помощью спецификатора глобуса D .

_% echo *(D)
..two .one none zero
_

Добавьте спецификатор глобуса N, чтобы расширение оказалось пустым в пустой директории: *(DN).


Примечание: вы можете получить результаты расширения имени файла в разных порядках (например, none, за которым следует _.one_, а затем _..two_), в зависимости от настроек _LC_COLLATE_, _LC_ALL_ и LANG переменные.

178
Gilles 'SO- stop being evil'
#!/bin/bash

shopt -s dotglob
mv Foo/* Bar/

От man bash

dotglob Если установлено, bash включает имена файлов, начинающиеся с '.' в результатах расширения пути.

24
SiegeX

Простой способ сделать это в bash

_mv {Foo/*,Foo/.*} Bar/
_

Но это также переместит каталоги.

Если вы хотите переместить все файлы, включая скрытые, но не хотите перемещать каталог, вы можете использовать цикл for и test.

for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;

11
Boris Month

Одним из способов является использование find:

find Foo/ -type f -exec mv -t Bar/ {} \+

-type f ограничивает команду поиска поиском файлов. Вы должны исследовать -type, -maxdepth, а также -mindepth опции find для настройки вашей команды для учета подкаталогов. Find имеет длинный, но очень полезный страница справочника .

4
Steven D

Попробуйте команду копирования cp:

$ cp -r myfolder/* destinationfolder

cp -r означает рекурсивное копирование, поэтому все папки и файлы будут скопированы.

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

$ rm -r myfolder

Подробнее: переместить все файлы из одного каталога в другой .

2
ucefkh

Для минимальных дистрибутивов Linux должно работать следующее. Сначала выполните базовый ход всех (при этом пропускаются скрытые файлы). Затем переместите все скрытые файлы (включая . а также .. который будет не фактически будет перемещен).

mv /sourceDir/* /destinationDir 2> /dev/null
mv /sourceDir/.* /destinationDir 2> /dev/null

Примечания: Если видимого содержимого нет, первая команда выдаст сообщение об ошибке. Вторая команда всегда выдаст ошибку о том, что она не может двигаться . а также ... Поэтому просто отправьте ошибки в /dev/null (как показано).

Если вам нужно это как однострочный, просто объедините их точкой с запятой:

mv /sourceDir/* /destinationDir 2> /dev/null; mv /sourceDir/.* /destinationDir 2> /dev/null
1
BuvinJ

Rsync - это еще один вариант:

rsync -axvP --remove-source-files sourcedirectory/ targetdirectory

Это работает, потому что в rsync конечный слэш имеет значение, sourcedirectory/ ссылается на содержимое каталога, а sourcedirectory ссылается на сам каталог.

Недостатком этого метода является то, что rsync будет очищать только файлы после перемещения, а не каталог. Таким образом, у вас осталось пустое дерево источников. Обходные пути для этого см .:

перемещать файлы и удалять каталоги с помощью rsync?

Поэтому, хотя это может быть неоптимальным для операций перемещения, оно может быть чрезвычайно полезным для операций копирования.

1
Grumbel

Ответ для bash/fish

Вот способ сделать это с помощью подстановочных знаков:

.[!.]* ..?* будет соответствовать все скрытые файлы кроме . а также ..

.[!.]* ..?* * будет соответствовать все файлы (скрытые или нет) кроме . а также ..

И чтобы ответить на конкретный пример этого вопроса вам нужно cd foo && mv .[!.]* ..?* * ../bar

Объяснение

.[!.]* соответствует именам файлов, начинающимся с одной точки, за которой следует любой символ, кроме точки (необязательно) , за которой следует любая строка. Это достаточно близко, но оно пропускает файлы, начинающиеся с двух точек, таких как ..foo. Чтобы включить такие файлы, мы добавляем ..?*, который соответствует именам файлов, начинающимся с двух точек, за которыми следует любой символ, (необязательно) , за которым следует любая строка.

Тест

Вы можете проверить эти шаблоны с помощью команд ниже. Я успешно пробовал их в bash и fish. Они терпят неудачу при sh, zsh, xonsh.

mkdir temp
cd temp
touch  a  .b  .bc  ..c  ..cd  ...d  ...de
ls .[!.]* ..?*
# you get this output:
          .b  .bc  ..c  ..cd  ...d  ...de
# cleanup
cd ..
rm -rf temp
1
ndemou

Я считаю, что это хорошо работает для Bash, и нет необходимости изменять параметры оболочки

mv sourcedir/{*,.[^.]*} destdir/

Правка:

Итак, как сказал G-man, мой первоначальный ответ не соответствует posix и во многом совпадает с ответом ndemou, приведенным выше, с одним изменением, которое заключается в использовании расширения скобок для создания списков строк, которые затем обрабатываются. Это просто означает, что вам не нужно cd в исходный каталог. Не очень большие изменения, но они разные.

пример: допустим, у вас уже есть следующий макет.

 $ tree -a
.
├── destdir
└── sourcedir
    ├── ..d1
    ├── ..d2
    ├── ..double
    ├── file-1
    ├── file-2
    ├── .hidden-1
    ├── .hidden-2
    ├── ...t1
    └── ...t2

В первоначальном вопросе упоминались только скрытые файлы с одним периодом, но, скажем, есть некоторые с двумя или более периодами в начале имени. Вы можете просто добавить дополнительное выражение в фигурные скобки. Затем мы можем выполнить

mv sourcedir/{*,.[!.]*,..?*} destdir/

Это расширяется до следующего:

mv sourcedir/file-1 sourcedir/file-2 sourcedir/.hidden-1 sourcedir/.hidden-2 sourcedir/..d1 sourcedir/..d2 sourcedir/..double sourcedir/...t1 sourcedir/...t2 destdir/

Теперь вы должны увидеть все файлы, расположенные в destdir :

 $ tree -a
.
├── destdir
│   ├── ..d1
│   ├── ..d2
│   ├── ..double
│   ├── file-1
│   ├── file-2
│   ├── .hidden-1
│   ├── .hidden-2
│   ├── ...t1
│   └── ...t2
└── sourcedir

Вы можете сделать несколько довольно крутых вещей с помощью фигурных скобок в bash с еще большим количеством дополнений в 4.x. Проверьте bash-hackers для некоторых изящных примеров.

0
cmndr sp0ck

Вы также можете найти и использовать обратные кавычки, чтобы выбрать файлы для команды перемещения. Передайте те в М.В.

То есть Для скрытых файлов

find Foo -maxdepth 1 | egrep '^Foo/[.]' # Output: .hidden

Так

mv `find Foo -maxdepth 1 | egrep '^Foo/[.]'` Bar # mv Foo/.hidden Bar

Перемещает только выбранные скрытые файлы в Bar:

mv `find Foo -maxdepth 1 | egrep '^Foo/.'` Bar # mv Foo/.hidden Foo/notHidden Bar

Перемещает все файлы в Foo в Bar, начиная с '.' в команде egrep действует как подстановочный знак без квадратных скобок.

^ _ означает, что совпадение начинается с начала строки.

Некоторые подробности egrep сопоставления с образцом можно найти здесь .

С помощью maxdepth 1 прекращает поиск в подкаталогах.

0
user3192145

Вдохновленный от этот ответ :

Без копирования файлов ...

rsync -ax --link-dest=../Foo/ Foo/ Bar

Предостережения:

  • --link-dest путь должен быть абсолютным или относительным к DESTINATION (Bar в примере)

  • Вы должны положить / после ИСТОЧНИКА (Foo/ в примере), в противном случае он скопирует папку SOURCE вместо содержимого.

0
palindrom