tìm với -execdir


15

Khi tôi chạy findvới -execdirtôi không nhận được kết quả như mong đợi.

Ví dụ:

mkdir -p a/b/c
find . -type d -execdir touch foo \;
$ tree a
a
├── b
   ├── c
   └── foo
└── foo

Thư mục ckhông chứa một footập tin. Làm thế nào để tôi có findthể truy cập và làm một cái gì đó cục bộ trong mỗi thư mục?

Câu trả lời:


18

Đối với mọi tệp phù hợp (tức là mọi thư mục), findchuyển sang thư mục chứa tệp đó (tức là thư mục mẹ của nó) và thực thi lệnh được chỉ định. Vì lệnh không sử dụng tên của trận đấu, nên nó sẽ không bao giờ hành động trên tất cả các thư mục. Đối với cây thư mục cụ thể này, bạn đang làm

(cd . && touch foo)        # because ./a matches
(cd ./a && touch foo)      # because ./a/b matches
(cd ./a/b && touch foo)    # because ./a/b/c matches

Để tạo một tệp trong mọi thư mục, bạn chỉ cần sử dụng -execthay vì -execdir, với điều kiện bạn thực hiện findcho phép {}bên trong một đối số (hầu hết, và đặc biệt tôi nghĩ tất cả các thư mục):

find . -type d -exec touch {}/foo +

Đối với tính di động POSIX, bạn sẽ cần phải thực hiện việc lắp ráp tên thư mục và tên cơ sở tệp theo cách thủ công.

find . -type d -exec sh -c 'touch "$0/foo"' {} \;

hoặc (nhanh hơn một chút)

find . -type d -exec sh -c 'for d; do touch "$d/foo"; done' _ {} +

Ngoài ra, bạn có thể sử dụng kết hợp ký tự đại diện đệ quy của bash. Coi chừng rằng (không giống như tính năng tương ứng trong ksh và zsh, và không giống như findlệnh của bạn ) bash đệ quy dưới các liên kết tượng trưng đến các thư mục.

shopt -s globstar
for d in **/*/; do touch -- "$d/foo"; done

Một giải pháp zsh:

touch ./**/(e\''REPLY+=foo'\')

FYI: man bashtrạng thái trong "-c": đối số sau lệnh_ chuỗi được gán cho tham số vị trí bắt đầu bằng $ 0, tuy nhiên "for d" sẽ lặp lại thông qua vị trí bắt đầu bằng $ 1. "_" là văn bản được gán cho $ 0 và sẽ không được sử dụng.
Chad Skeeter

3

Lệnh thực thi trong mọi thư mục chứa tệp phù hợp. Vì ckhông chứa thư mục, nó không khớp và do đó sẽ không được chạy ở đó.

Giải pháp là thêm tên thư mục vào đối số execdir, như vậy:

find . -type d -execdir touch {}/foo \;

2

Từ man file

   -execdir command {} +
          Like  -exec,  but  the  specified  command is run from the subdirectory containing the matched file

Thư mục phù hợp của bạn cnằm trong bthư mục để đó là nơi thực thi được chạy từ đó. Nó sẽ hoạt động như bạn mong đợi nếu bạn đang tìm kiếm các tập tin thay vì các thư mục.

Bạn có thể có thể đạt được những gì bạn muốn bằng cách gửi các thư mục đến xargsvì nó sẽ được cung cấp danh sách đầy đủ các thư mục.

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.