sentuh semua folder dalam direktori

13

Saya mencoba memperbarui cap waktu semua folder di cwd menggunakan ini:

for file in `ls`; do touch $file; done

Tapi sepertinya itu tidak berhasil. Ada ide kenapa?

javamonkey79
sumber

Jawaban:

21

Semua jawaban sejauh ini (dan juga contoh Anda dalam pertanyaan) mengasumsikan bahwa Anda ingin touchsemua yang ada di direktori, meskipun Anda mengatakan "sentuh semua folder". Jika ternyata direktori berisi file dan folder dan Anda hanya ingin memperbarui folder, Anda dapat menggunakan find:

$ find . -maxdepth 1 -mindepth 1 -type d -exec touch {} +

Atau jika findimplementasi Anda tidak mendukung predikat non-standar -mindepth/ -maxdepth:

$ find . ! -name . -prune -type d -exec touch {} +

Ini:

$ touch -c -- */

Harus bekerja di sebagian besar cangkang kecuali bahwa:

  • itu juga akan touch symlink ke direktori di samping direktori polos
  • itu akan menghilangkan yang tersembunyi
  • jika tidak ada direktori atau symlink ke direktori, itu akan menciptakan sebuah file yang bernama *dalam kerang selain csh, tcsh, zsh, fishatau Thompson shell (yang akan melaporkan kesalahan sebagai gantinya). Di sini, kami menggunakan -cuntuk mengatasinya, meskipun itu masih bisa touchdisebut file non-direktori *.

Dengan zsh, touchhanya untuk direktori, termasuk yang tersembunyi:

touch -- *(D/)
Michael Mrozek
sumber
Tentang apa '{} \ +' itu?
javamonkey79
3
The {} \+khusus findsintaks - baca halaman manual untuk lebih. Saya pikir touch -c ./*/akan bekerja juga.
jw013
2
Anda harus memasukkan -maxdepth 1ke perintah, sehingga findtidak berulang menjadi subfolder. OP tampaknya hanya ingin menyentuh folder-folder itu di cwd, bukan subfolder.
Steven Senin
1
@ jw013 Pasti - Anda tetap melampirkan ide-ide bagus untuk jawaban orang lain :)
Michael Mrozek
Mengapa Anda keluar dari karakter +? Apakah ada kerang yang menafsirkannya?
Witiko
11

Mencoba

touch ./*

Itu menghindari forloop yang tidak perlu yang akan menelurkan proses baru untuk setiap file tunggal dan bekerja untuk semua nama file, bahkan yang dengan spasi atau yang terlihat seperti opsi (seperti -t). Satu-satunya waktu itu tidak akan berhasil adalah jika Anda tidak memiliki file (non-dot) di direktori dalam hal ini Anda akhirnya akan membuat file bernama *. Untuk menghindari itu, untuk kasus tertentu touchsebagian besar implementasi memiliki -copsi (juga disebut --no-createdalam versi GNU) untuk tidak membuat file yang tidak ada, yaitu

touch -c ./*

Lihat juga referensi yang baik dalam jawaban jasonwryan ini serta ini salah satu .

jw013
sumber
1
Apa yang akan terjadi jika Anda memiliki 1 juta folder di CDD?
Steven Senin
Jika Anda mengalami masalah jenis "daftar argumen terlalu lama", mungkin lebih baik beralih ke alat "berat" seperti find . -type d -maxdepth1 -print0 | xargs -0 touch, atau jawaban MichaelMrozek di atas.
jw013
7

Anda seharusnya tidak mencoba mem-parsing output darils .

Juga, Anda harus mengutip Anda "$file"untuk menangkap spasi. Lihat http://www.grymoire.com/Unix/Quote.html

Sesuatu seperti ini mungkin mencapai apa yang Anda cari:

for file in *; do touch "$file"; done

Lihat dua Bash Pitfalls pertama untuk penjelasan yang lebih menyeluruh.

jasonwryan
sumber
2
Tutup tetapi tidak cukup. A touch ./*harus bekerja dalam banyak kasus. Benar-benar tidak perlu untuk forloop karena touchdapat mengambil banyak file, dan Anda perlu ./untuk menangani file dengan nama seperti --helpdengan benar. Ini adalah sumber yang bagus untuk masalah ini.
jw013
Mengapa '*' berfungsi?
javamonkey79
@ javamonkey79 Ini shell globbing .
jw013
1
@ jw013 Poin luar biasa: dan terima kasih atas tautan beroda.
jasonwryan
Catatan yang *tidak menangkap file dan direktori yang namanya dimulai dengan titik. Salah satu cara untuk memperbaikinya adalah dengan mengaktifkan dotglobopsi shell via shopt -s dotglob.
Witiko
-1
for file in `find .`; do touch $file; done
mikematik
sumber