chạm vào tất cả các thư mục trong một thư mục


13

Tôi đang cố gắng cập nhật dấu thời gian của tất cả các thư mục trong cwd bằng cách sử dụng:

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

Nhưng nó dường như không hoạt động. Bất cứ ý tưởng tại sao?

Câu trả lời:


21

Tất cả các câu trả lời cho đến nay (cũng như ví dụ của bạn trong câu hỏi) cho rằng bạn muốn touchmọi thứ trong thư mục, mặc dù bạn đã nói "chạm vào tất cả các thư mục". Nếu hóa ra thư mục chứa các tệp và thư mục và bạn chỉ muốn cập nhật các thư mục, bạn có thể sử dụng find:

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

Hoặc nếu findviệc triển khai của bạn không hỗ trợ các vị từ -mindepth/ tiêu chuẩn -maxdepth:

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

Điều này:

$ touch -c -- */

Nên hoạt động trong hầu hết các shell ngoại trừ:

  • nó cũng sẽ touch liên kết đến các thư mục ngoài các thư mục đơn giản
  • nó sẽ bỏ qua những cái ẩn
  • nếu không có thư mục hoặc liên kết tượng trưng đến thư mục, nó sẽ tạo ra một tập tin gọi là *ở vỏ ngoài csh, tcsh, zsh, fishhoặc vỏ Thompson (mà sẽ báo cáo một lỗi thay vì). Ở đây, chúng tôi đang sử dụng -cđể làm việc xung quanh nó, mặc dù đó vẫn có thể touchlà một tệp không có thư mục được gọi *.

Với zsh, touchchỉ các thư mục, bao gồm cả những thư mục ẩn:

touch -- *(D/)

'{} \ +' Là gì?
javamonkey79

3
Các {} \+là đặc biệt findcú pháp - đọc man page để biết thêm. Tôi nghĩ rằng touch -c ./*/sẽ làm việc như là tốt.
jw013

2
Bạn nên bao gồm -maxdepth 1lệnh, để findkhông lặp lại thành các thư mục con. OP dường như chỉ muốn chạm vào các thư mục đó trong cwd, không phải các thư mục con.
Steven Thứ Hai

1
@ jw013 Nó sẽ - bạn tiếp tục gắn những ý tưởng hay với câu trả lời của người khác :)
Michael Mrozek

Tại sao bạn thoát khỏi ký tự +? Có vỏ giải thích nó?
Witiko

11

Thử

touch ./*

Nó tránh những thứ không cần thiết for vòng lặp sẽ tạo ra một quy trình mới cho mỗi tệp duy nhất và hoạt động cho tất cả các tên tệp, ngay cả những tệp có khoảng trắng hoặc các tệp trông giống như tùy chọn (như -t). Lần duy nhất nó không hoạt động là nếu bạn không có tệp (không phải dấu chấm) trong thư mục trong trường hợp bạn sẽ tạo một tệp có tên *. Để tránh điều đó, đối với trường hợp cụ thể của touchhầu hết các triển khai có một -ctùy chọn (còn được gọi --no-createtrong các phiên bản GNU) để không tạo các tệp không tồn tại, tức là

touch -c ./*

Xem thêm các tài liệu tham khảo tốt trong câu trả lời jasonwryan của cũng như này một .


1
Điều gì sẽ xảy ra nếu bạn có 1 triệu thư mục trong cwd?
Steven Thứ Hai

Nếu bạn gặp phải vấn đề loại "danh sách đối số quá dài", có lẽ tốt nhất nên chuyển sang các công cụ "nặng hơn" như find . -type d -maxdepth1 -print0 | xargs -0 touch, hoặc câu trả lời của MichaelMrozek ở trên.
jw013

7

Bạn không nên cố gắng phân tích đầu ra củals .

Ngoài ra, bạn nên trích dẫn của bạn "$file" để nắm bắt bất kỳ khoảng trắng. Xem http://www.grymoire.com/Unix/Quote.html

Một cái gì đó như thế này có thể đạt được những gì bạn đang có sau:

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

Xem hai cạm bẫy Bash đầu tiên để được giải thích kỹ hơn.


2
Gần nhưng không hẳn. A touch ./*nên làm việc trong hầu hết các trường hợp. Thực sự không cần forvòng lặp vì touchcó thể lấy nhiều tệp và bạn cần ./xử lý các tệp có tên như --helpđúng. Đây là một nguồn tốt về chủ đề này.
jw013

Tại sao '*' hoạt động?
javamonkey79

@ javamonkey79 Nó của vỏ globbing .
jw013

1
@ jw013 Điểm tuyệt vời: và cảm ơn bạn đã liên kết bánh xe.
jasonwryan

Lưu ý rằng *không chụp các tệp và thư mục có tên bắt đầu bằng dấu chấm. Một cách để khắc phục đó là kích hoạt dotglobtùy chọn shell thông qua shopt -s dotglob.
Witiko

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.