Как переместить все файлы в каталоге (включая скрытые) в другой каталог?
Например, если у меня есть папка «Foo» с файлами «.hidden» и «notHidden» внутри, как мне переместить оба файла в каталог с именем «Bar»? Следующее не работает, так как «.hidden» файл остается в «Foo».
mv Foo/* Bar/
Попробуй сам.
mkdir Foo
mkdir Bar
touch Foo/.hidden
touch Foo/notHidden
mv Foo/* Bar/
Ответы:
Zsh
или же
(Не указывайте,
(N)
если каталог не пуст.)удар
ksh93
Если вы знаете, что каталог не пуст:
Стандарт (POSIX) ш
Если вы хотите, чтобы
mv
команда возвращала статус ошибки, даже если она прошла успешно, это намного проще:GNU найти и GNU MV
Стандартная находка
Если вы не возражаете перейти на исходный каталог:
Вот более подробно о контроле соответствия файлов точек в bash, ksh93 и zsh.
удар
Установите
dotglob
опцию .Существует также более гибкая
GLOBIGNORE
переменная , которую вы можете установить в список символов подстановки, разделенных двоеточиями, чтобы игнорировать их. Если не установлено (настройка по умолчанию), оболочка ведет себя так, как если бы значение было пустым, еслиdotglob
установлено, и как если бы значение было,.*
если опция не установлена. См. Расширение имени файла в руководстве. Повсеместная каталоги.
и..
всегда опущена, если.
не будет сопоставляться явно с шаблоном.ksh93
Установите
FIGNORE
переменную . Если не установлено (настройка по умолчанию), оболочка ведет себя так, как если бы значение было.*
. Чтобы игнорировать.
и..
, они должны совпадать явно (руководство в ksh 93s + 2008-01-31 утверждает, что.
и..
всегда игнорируется, но это не правильно описывает реальное поведение).Вы можете включать точечные файлы в шаблон , сопоставляя их явно.
Чтобы расширение оказалось пустым, если каталог пуст, используйте параметр
N
сопоставления с образцом:~(N)@(*|.[^.]*|..?*)
или~(N:*|.[^.]*|..?*)
.Zsh
Установите
dot_glob
опцию ..
и..
никогда не совпадают, даже если шаблон.
явно соответствует ведущему .Вы можете включать точечные файлы в определенный шаблон с помощью
D
квалификатора glob .Добавьте
N
Глоб классификатор , чтобы сделать расширение выйти пустой в пустом каталоге:*(DN)
.Примечание: вы можете получить имя файла результатов расширения в различных порядках (например, с
none
последующим.one
последующим..two
) , основываясь на ваших настройкахLC_COLLATE
,LC_ALL
иLANG
переменных.источник
nullglob
? Было бы более разумно прервать выполнениеmv
команды (например, fish, csh / tcsh, zsh (без(N)
) do или bash с failglob), чем запускатьmv /Bar/
команду, которая не имеет большого смысла..
и..
никогда не совпадает (как в других разумных оболочках, таких как zsh, fish, pdksh и производные), даже если впоследствии вы выключите dotglob. (GLOBIGNORE=:; shopt -u dotglob; echo .*
не будет выводить.
и..
). установка GLOBIGNORE в.:..
или.
или:
иметь тот же эффект.ksh93
всегда игнорирует.
и,..
кажется, был сломан междуksh93k+
(где это работало) иksh93m
(где это больше не работает). Обратите внимание, что это плохо, так какksh93
будет принимать значение FIGNORE из среды, поэтому, например,FIGNORE='!(..)'
env var может создать хаос.Из
man bash
источник
mv
том, что ты ждешь, что этот файлFoo/*
не существует. Интересно, что еслиFoo
он доступен для поиска, но не доступен для чтения, и там есть файл, вызываемый*
там, вы не получите никакой ошибки, этот файл будет перемещен, но не другие файлы в каталоге.bash
имеетfailglob
опцию , чтобы он ведет себя больше какzsh
,fish
илиcsh
/tcsh
и прервать команду с ошибкой , когда Glob не может быть расширен вместо этого поддельного поведения оставляя Glob как есть.Простой способ сделать это в
bash
этоНо это также переместит каталоги.
Если вы хотите переместить все файлы, включая скрытые, но не хотите перемещать каталог, вы можете использовать цикл for и test.
for i in $(ls -d {Foo/*,Foo/.*});do test -f $i && mv -v $i Bar/; done;
источник
Одним из способов является использование
find
:-type f
Ограничивает команды поиска для поиска файлов. Вам следует изучить параметры-type
,-maxdepth
и-mindepth
,find
чтобы настроить вашу команду для учета подкаталогов. Find имеет длинную, но очень полезную справочную страницу .источник
Foo/
, а не подкаталоги и другие файлы.Попробуйте команду копирования
cp
:cp -r
означает копирование рекурсивно, поэтому все папки и файлы будут скопированы.Вы можете использовать команду удаления,
rm
чтобы удалить папку:Подробнее: переместить все файлы из одного каталога в другой .
источник
Rsync - это еще один вариант:
Это работает, потому что в rsync косая черта имеет значение,
sourcedirectory/
относится к содержимому каталога, аsourcedirectory
относится к самому каталогу.Недостатком этого метода является то, что rsync будет очищать только файлы после перемещения, а не каталог. Таким образом, у вас остается пустое дерево источников. Обходные пути для этого см .:
Перемещать файлы и удалять каталоги с помощью rsync?
Поэтому, хотя это может быть неоптимальным для операций перемещения, оно может быть чрезвычайно полезным для операций копирования.
источник
Ответ для Баш / Рыба
Вот способ сделать это с помощью подстановочных знаков:
.[!.]* ..?*
будет соответствовать всем скрытым файлам, кроме.
и..
.[!.]* ..?* *
будет соответствовать всем файлам (скрытым или нет), кроме.
и..
И чтобы ответить на конкретный пример этого вопроса вам нужно
cd foo && mv .[!.]* ..?* * ../bar
объяснение
.[!.]*
соответствует именам файлов, начинающимся с одной точки, за которой следует любой символ, кроме точки, за которой может следовать любая строка. Это достаточно близко, но оно пропускает файлы, начинающиеся с двух точек, например..foo
. Чтобы добавить такие файлы, мы добавляем..?*
совпадения с именами файлов, начинающимися с двух точек, за которыми следует любой символ, за которым может следовать любая строка.Контрольная работа
Вы можете проверить эти шаблоны с помощью команд ниже. Я успешно пробовал их в bash и fish. Они терпят неудачу при sh, zsh, xonsh.
источник
Вы также можете найти и использовать обратные кавычки, чтобы выбрать файлы для команды перемещения. Передайте те в М.В.
Т.е. для скрытых файлов
Так
Перемещает только выбранные скрытые файлы в
Bar
:Перемещает все файлы в Foo в Bar, начиная с '.' в команде egrep действует как подстановочный знак без квадратных скобок.
^
Характер обеспечивает матч начинается с начала строки.Некоторые подробности
egrep
сопоставления с образцом можно найти здесь .Используя
maxdepth 1
стопы найдите от входа в подкаталоги.источник
Вдохновленный этим ответом :
Без копирования файлов ...
Предостережения:
--link-dest
путь должен быть абсолютным или относительным к DESTINATION (Bar
в примере)Вы должны поставить
/
после SOURCE (Foo/
в примере), в противном случае он скопирует папку SOURCE вместо содержимого.источник
Я считаю, что это хорошо работает для Bash и нет необходимости изменять параметры оболочки
РЕДАКТИРОВАТЬ:
Итак, как сказал G-man, мой первоначальный ответ не соответствует требованиям posix и во многом совпадает с ответом ndemou, приведенным выше, с одним изменением, которое заключается в использовании расширения скобок для создания списков строк, которые затем обрабатываются. Это просто означает, что вам не нужно
cd
заходить в исходный каталог. Не очень большие изменения на самом деле, но они разные.пример: допустим, у вас уже есть следующий макет.
В первоначальном вопросе упоминались только скрытые файлы с одним периодом, но, скажем, есть некоторые с двумя или более периодами в начале имени. Вы можете просто добавить дополнительное выражение в фигурные скобки. Затем мы можем выполнить
Это расширяется до следующего:
Теперь вы должны увидеть все файлы, расположенные в destdir :
Вы можете сделать несколько довольно крутых вещей с помощью фигурных скобок в bash с еще большим количеством дополнений в 4.x. Проверьте bash-хакеров для некоторых изящных примеров.
источник
..
, и (2) чтобы быть POSIX-совместимым , вы должны использовать!
вместо^
; то есть{*,.[!.]*}
.cd
заходить в исходный каталог, чтобы воздействовать на файлы или записывать одни и те же пути к файлам снова и снова, чтобы выразить пути ко всем файлам. Я вскоре обновлю пример, чтобы дать читателям более полное представление о том, о чем я говорю.Для минимальных дистрибутивов Linux должно работать следующее. Сначала выполните базовый ход всех (при этом пропускаются скрытые файлы). Затем переместите все скрытые файлы (включая
.
и..
которые на самом деле не будут перемещены).Примечания. Если видимого содержимого нет, первая команда выдаст сообщение об ошибке. Вторая команда всегда выдаст ошибку о том, что она не может двигаться
.
и..
. Таким образом, просто направьте ошибки в/dev/null
(как показано).Если вам нужно это как однострочный, просто объедините их точкой с запятой:
источник