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

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

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

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

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

136
задан 14 June 2014 в 05:21

8 ответов

Можно сделать это:

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

Можно поместить

shopt -s dotglob

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

См. http://mywiki.wooledge.org/glob


Другой подход для копирования точечных файлов:

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

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

147
ответ дан 22 November 2019 в 22:54

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

cp -Rp . /desired/directory

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

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

mv $(ls -A) /desired/directory
8
ответ дан 22 November 2019 в 22:54

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

Для копирования файлов даже с шариком необходимо снабдить префиксом файл . такой как mv -u .* foo и затем .foo будет appearn как foo/.foo при перемещении.

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

2
ответ дан 22 November 2019 в 22:54

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

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
43
ответ дан 22 November 2019 в 22:54

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

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

это проигнорирует те текущие и родительские указатели dir.

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

11
ответ дан 22 November 2019 в 22:54

Таким образом, мы имеем:

a
|-- .foo
`-- bar

и:

b

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

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

$ mv --help

Затем я нашел свою любовь:

$ mv a/ b/ -T

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

- T, - no-target-directory рассматривайте DEST как нормальный файл

0
ответ дан 22 November 2019 в 22:54

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

cp -Rp source-directory/. .
-1
ответ дан 22 November 2019 в 22:54

В моем случае я просто пытался mv единственный скрытый файл и это были решением:

FILE=.myHiddenFile
mv "$FILE" dest/

Объяснение

Сначала я пробовал:

mv .myHiddenFile dest/

Но это продолжало производить ошибку:

mv: cannot stat '.myHiddenFile': No such file or directory

Даже при том, что a ls -al показал что файл и dest/ существовавший.

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

0
ответ дан 22 November 2019 в 22:54

Другие вопросы по тегам:

Похожие вопросы: