Відповіді:
Відмова: Ця відповідь стосується Bash конкретно, але значна частина стосується питання щодо глобальних моделей!
Зоряний персонаж ( *
) - це майна. Існує певний набір символів, який він займе місце, і перший символ, який є крапкою ( .
), не є одним з них. Це особливий випадок саме тому, як працюють файлові системи Unix, файли, які починаються з крапки, вважаються "прихованими". Це означає, що такі інструменти, як cp
, ls
і т. Д., Не будуть "бачити" їх, якщо прямо не вказано.
Спершу давайте створимо деякі зразкові дані.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Отже, тепер ми маємо наступне:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Тепер пограємо в кілька ігор. Ви можете скористатися командою, echo
щоб перерахувати, що конкретний підстановник ( *
) буде для даної команди на зразок:
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
$ echo reg*
regdir1 regdir2 regfile1 regfile2 regfile3
$ echo .*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2
$ echo .* *
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
$ echo .dotdir*
.dotdir1 .dotdir2
Ви можете скористатися командою, shopt -s dotglob
щоб змінити поведінку *
так, що крім файлів, подібних до regfile1
нього, також буде відповідати .dotfile1
.
уривок зі bash
сторінки man
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Приклад:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Ви можете повернути цю поведінку за допомогою цієї команди:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Для вас ви говорите, cp
що хочете скопіювати всі файли, які відповідають шаблону *
, а файлів немає.
$ cp foo/.* .
Або ви можете зробити це, якщо ви хочете, щоб все було в foo
папці:
$ cp foo .
Або ви можете бути явними:
$ cp foot/.* foo/* .
Більш компактна форма із застосуванням розширення дужок у bash
:
$ cp foo/{.,}* .
У будь-який час ви можете використовувати echo
фокус, щоб побачити запропоновані вами шаблони файлів (це вигадний термін для того, до складу якої належить зірка).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
До речі, якщо ви збираєтесь скопіювати каталог файлів + інші каталоги, зазвичай це потрібно зробити рекурсивно, це -R
перехід до cp
:
$ cp -R foo/. .
shopt -s dotglob
, echo *
а потім дає:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
зазвичай не працюватиме, оскільки cp
відмовиться копіювати foo
над собою, ви, мабуть, мали на увазі cp -R foo/. .
. (зверніть увагу, що cp -R
це стандарт).
zsh
не включає .
і ..
в розширення .*
. В zsh
, якщо шаблон не відповідає, то команда переривається (цілком здраво знову), так що в загальному випадку, cp foo/{,.}* .
НЕ вийде, якщо ні не приховано або нет не-прихованих файлів.
shopt
не існує.
З zsh
, типовим способом є використання D
класифікатора глобу (для включення файлів [D] ot):
cp foo/*(D) .
Зауважте, що з або без D
zsh глобуси ніколи не включають .
ні ..
(як ви очікували).
Оболонка розглядає ці файли як приховані, коли вона вирішує *
символ, тому cp
не отримує жодне з цих імен файлів як аргументів.
Ви можете скопіювати їх, чітко вказавши cp foo/.* .
Якщо ви хочете зробити це скопіювати всі файли та каталоги з одного місця в інше, ви можете використовувати стандартну rsync
команду. У наведеному вище прикладі:
mkdir foo && touch foo/.test
rsync -a foo/ .
буде рекурсивно копіювати весь вміст foo
, включаючи приховані файли та приховані каталоги, у поточний каталог. Косою косою рисою в кінці foo/
є важливим для rsync; з нею foo
копіюється лише вміст , без цього rsync також буде копіювати foo
. Наприклад:-
mkdir src && mkdir dest && touch src/.test
rsync -a src dest // copies 'src' contents to 'dest/src'
rsync -a src/ dest // copies 'src' contents to 'dest'
Існує багато інших варіантів налаштування rsync, включаючи копіювання між машинами.
dotglob
транслюютьсяglobdots
по Zsh , яка неприпустиме ім'я опції для Баша .