Jawaban:
Penafian: Jawaban ini berkaitan dengan Bash secara khusus tetapi sebagian besar berlaku untuk pertanyaan mengenai pola glob!
Karakter bintang ( *
) adalah wildcard. Ada serangkaian karakter tertentu yang akan menggantikannya dan karakter pertama menjadi titik ( .
) bukan salah satunya. Ini adalah kasus khusus hanya karena cara kerja sistem file Unix, file yang dimulai dengan titik dianggap "tersembunyi". Itu berarti bahwa alat-alat seperti cp
, ls
, dll tidak akan "melihat" mereka kecuali secara eksplisit diperintahkan untuk melakukannya.
Pertama mari kita buat beberapa data sampel.
$ mkdir .dotdir{1,2} regdir{1,2}
$ touch .dotfile{1,2} regfile{1..3}
Jadi sekarang kita memiliki yang berikut:
$ tree -a
.
|-- .dotdir1
|-- .dotdir2
|-- .dotfile1
|-- .dotfile2
|-- regdir1
|-- regdir2
|-- regfile1
|-- regfile2
`-- regfile3
Sekarang mari kita mainkan beberapa game. Anda dapat menggunakan perintah echo
untuk mencantumkan apa wildcard tertentu ( *
) akan untuk perintah yang diberikan seperti:
$ 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
Anda dapat menggunakan perintah shopt -s dotglob
untuk mengubah perilaku *
sehingga selain file seperti regfile1
itu juga akan cocok .dotfile1
.
kutipan dari bash
halaman manual
dotglob If set, bash includes filenames beginning with a `.' in the results
of pathname expansion.
Contoh:
$ shopt -s dotglob
$ echo *
.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
Anda dapat mengembalikan perilaku ini dengan perintah ini:
$ shopt -u dotglob
$ echo *
regdir1 regdir2 regfile1 regfile2 regfile3
Untuk Anda, Anda memberi tahu cp
bahwa Anda ingin menyalin semua file yang sesuai dengan pola *
, dan tidak ada file.
$ cp foo/.* .
Atau Anda dapat melakukan ini jika Anda ingin semua yang ada di foo
folder:
$ cp foo .
Atau Anda bisa eksplisit:
$ cp foot/.* foo/* .
Bentuk yang lebih ringkas menggunakan ekspansi brace di bash
:
$ cp foo/{.,}* .
Kapan saja Anda dapat menggunakan echo
trik untuk melihat apa pola file yang Anda usulkan (itulah istilah mewah untuk bagian bintang itu).
$ echo {.,}*
. .. .dotdir1 .dotdir2 .dotfile1 .dotfile2 abc regdir1 regdir2 regfile1 regfile2 regfile3
Kebetulan jika Anda akan menyalin direktori file + direktori lain, Anda biasanya ingin melakukan ini secara rekursif, itulah -R
peralihan ke cp
:
$ cp -R foo/. .
shopt -s dotglob
, echo *
kemudian memberikan:.dotdir1 .dotdir2 .dotfile1 .dotfile2 regdir1 regdir2 regfile1 regfile2 regfile3
cp -r foo .
biasanya tidak akan berfungsi karena cp
akan menolak untuk menyalin foo
sendiri, mungkin maksud Anda cp -R foo/. .
. (perhatikan itu cp -R
yang standar).
zsh
tidak termasuk .
dan ..
dalam perluasan .*
. Dalam zsh
, jika suatu pola tidak cocok, perintah dibatalkan (cukup masuk akal lagi), sehingga dalam kasus umum, cp foo/{,.}* .
akan gagal jika tidak ada file yang tersembunyi atau tidak ada yang tersembunyi.
shopt
tidak ada.
Dengan zsh
, cara tipikal adalah menggunakan D
kualifikasi glob (untuk memasukkan [D] file):
cp foo/*(D) .
Perhatikan bahwa dengan atau tanpa D
, gumpalan zsh tidak pernah termasuk .
atau ..
(seperti yang Anda harapkan).
Jika yang ingin Anda lakukan adalah menyalin semua file & direktori dari satu tempat ke tempat lain, Anda dapat menggunakan rsync
perintah standar . Dalam contoh yang Anda berikan di atas:
mkdir foo && touch foo/.test
rsync -a foo/ .
akan secara rekursif menyalin semua konten foo
, termasuk file tersembunyi dan direktori tersembunyi, ke direktori saat ini. Garis miring pada akhir foo/
adalah penting untuk rsync; dengan itu hanya isi foo
yang disalin, tanpa itu rsync akan menyalin foo
juga. Sebagai contoh:-
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'
Ada banyak opsi lain yang tersedia untuk rsync, termasuk menyalin antar mesin.
dotglob
diterjemahkanglobdots
oleh zsh yang merupakan nama opsi yang tidak valid untuk bash .