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

90

Я переношу свой домашний каталог из старой системы в новую, и tarball, который я сделал, содержит все, включая скрытые файлы, такие как .bashrc. Однако, когда я перемещаю содержимое распакованного tarball (который находится в / tmp) в мой новый домашний каталог, скрытые файлы не копируют ( mv /tmp/home/rcook/* /home/rcook/ ). Как я могу заставить mv перемещать их?

На самом деле, я думаю, что проблема не в mv, а в том, что он сфокусирован на bash. Если я это сделаю:

mkdir a
mkdir b
touch a/.foo
touch a/bar
mv a/* b/
ls -a a/ b/

Я вижу это:

a/:
.  ..  .foo

b/:
.  ..  bar

a/.foo не двигался. Итак, как я могу получить подстановочный знак * для поиска скрытых файлов?

Да, я полагаю, я мог распаковать tarball прямо в мой домашний каталог, но tarball распаковывается в home/rcook/... , и я хочу быть уверенным, что перезаписываю новый .bashrc и т. д. со старыми, настроенными версиями, и знание того, как находить и перемещать скрытые файлы, является полезным навыком. Предложения?

В некоторых ответах предлагается сделать что-то вроде mv src/.* dest/ . Тем не менее, я попробовал это в своих тестовых каталогах и получил ошибки. Начиная с:

rcook$ ls -a a/ b/
a/:
.  ..  bar  .foo

b/:
.  ..
rcook$ mv a/.* b/
mv: cannot move 'a/.' to 'b/.': Device or resource busy
mv: cannot remove 'a/..': Is a directory
rcook$ ls -a a/ b/
a/:
.  ..  bar

b/:
.  ..  .foo

Что я делаю неправильно?

    
задан Randall Cook 21.02.2013 в 20:14
источник

7 ответов

101

Вы можете сделать это:

shopt -s dotglob
mv /tmp/home/rcook/* /home/rcook/

Вы можете поместить

shopt -s dotglob

в вашем ~/.bashrc , если вы хотите, чтобы он был по умолчанию.

См. Ссылка

Другой способ копирования файлов точек:

mv /tmp/home/rcook/.[!.]* /home/rcook/

Не используйте шаблон ..* , поскольку он соответствует .. (указатель на родительский каталог). Если есть файлы, имя которых начинается с двух точек ( ..something ), также используйте шаблон ..?* .

    
ответ дан Gilles Quenot 21.02.2013 в 20:16
источник
19

В ваших дополнениях вы получили ошибки, но код все еще работал. Единственное, что нужно добавить, это то, что вы сказали only копировать файлы точек. Попробуйте:

mv src/* src/.* dst/

Вы все равно получите ошибки для. и .. записи, что хорошо. Но движение должно быть успешным.

~/scratch [andrew] $ mv from/* from/.* to/
mv: cannot move ‘from/.’ to ‘to/.’: Device or resource busy
mv: cannot remove ‘from/..’: Is a directory
~/scratch [andrew] $ ls -a from/ to/
from/:
.  ..

to/:
.  ..  test  .test
    
ответ дан Andrew Schwartz 03.01.2014 в 19:47
9

Если вы ls -l в каталоге, вы увидите . и .. среди перечисленных файлов. Итак, я думаю, что mv .* /dest учитывает эти указатели. Попробуйте:

mv /tmp/home/rcook/{*,.[^.]*,..?*} /home/rcook/

это будет игнорировать те текущие и родительские указатели-указатели.

Вы получите сообщение об ошибке, если любой из трех шаблонов * , [^.]* или ..?* не соответствует файлу, поэтому вы должны включать только те, которые соответствуют.

    
ответ дан Azamat 14.06.2014 в 14:20
3

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

cp -Rp . /desired/directory

, то вы можете удалить исходные файлы в текущем каталоге

В качестве альтернативы, если вы знаете, что файлы названы безопасно (без пробелов, подстановочных знаков, непечатаемых символов), вы можете сделать что-то вроде этого

mv $(ls -A) /desired/directory
    
ответ дан Drake Clarris 21.02.2013 в 23:03
2

На Linux нет такой вещи, как «скрытые» файлы. Файлы, начинающиеся с точки, по умолчанию скрыты от файлов.

Чтобы скопировать файлы даже с помощью glob, вам необходимо префикс файла . , например mv -u .* foo , а затем .foo будет отображаться как foo/.foo при перемещении.

Параметр -u будет перемещать файлы только в том случае, если источник является более новым или отсутствует назначение. Или вы можете просто игнорировать ошибки в перемещении . и .. , поскольку они являются специальными файлами и не могут быть перемещены, но они попадают в файл .* glob оболочкой.

    
ответ дан dobey 21.02.2013 в 20:17
0

Итак, мы имеем:

a
|-- .foo
'-- bar

и

b

Я нашел огромное время для поиска лучшего решения, чем все ответы здесь.

Затем я взял 30 секунд для этой команды:

$ mv --help

Тогда я нашел свою любовь:

$ mv a/ b/ -T

Примечание. Я даже не понимаю аргумент -T . Он просто сделал то, что мне нужно. Здесь говорится:

  

-T, --no-target-directory обрабатывает DEST как обычный файл

    
ответ дан user433901 28.07.2015 в 02:42
0

Если вы хотите скопировать файлы, включая скрытые файлы, в текущий каталог, в котором вы находитесь.

cp -Rp source-directory/. .
    
ответ дан Rick 05.09.2016 в 02:51