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 echountuk 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 dotglobuntuk mengubah perilaku *sehingga selain file seperti regfile1itu juga akan cocok .dotfile1.
kutipan dari bashhalaman 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 cpbahwa 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 foofolder:
$ 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 echotrik 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 -Rperalihan 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 cpakan menolak untuk menyalin foosendiri, mungkin maksud Anda cp -R foo/. .. (perhatikan itu cp -Ryang standar).
zshtidak 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.
shopttidak 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 rsyncperintah 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 fooyang disalin, tanpa itu rsync akan menyalin foojuga. 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.
dotglobditerjemahkanglobdotsoleh zsh yang merupakan nama opsi yang tidak valid untuk bash .