temukan dengan -execdir

15

Ketika saya berlari finddengan -execdirsaya tidak mendapatkan hasil yang saya harapkan.

Sebagai contoh:

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

Direktori ctidak mengandung foofile. Bagaimana saya bisa findmengunjungi dan melakukan sesuatu secara lokal di setiap direktori?

Marcus Junius Brutus
sumber

Jawaban:

18

Untuk setiap file yang cocok (yaitu setiap direktori), findberalih ke direktori yang berisi itu (yaitu direktori induknya) dan menjalankan perintah yang ditentukan. Karena perintah itu tidak menggunakan nama pertandingan, itu tidak akan bertindak pada semua direktori. Untuk pohon direktori khusus ini, Anda lakukan

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

Untuk membuat file di setiap direktori, Anda bisa menggunakan -execalih-alih -execdir, asalkan implementasi Anda findmengizinkan {}di dalam argumen (kebanyakan, dan khususnya saya pikir semua):

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

Untuk portabilitas POSIX, Anda perlu melakukan perakitan nama direktori dan nama basis file secara manual.

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

atau (sedikit lebih cepat)

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

Atau, Anda dapat menggunakan pencocokan wildcard rekursif bash. Waspadalah bahwa (tidak seperti fitur yang sesuai di ksh dan zsh, dan tidak seperti findperintah Anda ) bash berulang di bawah tautan simbolis ke direktori.

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

Solusi zsh:

touch ./**/(e\''REPLY+=foo'\')
Gilles 'SANGAT berhenti menjadi jahat'
sumber
FYI: man bashstatus di bawah "-c": argumen setelah command_string ditugaskan untuk parameter posisi yang dimulai dengan $ 0, namun "untuk d" akan beralih melalui parameter posisi yang dimulai dengan $ 1. "_" adalah teks yang ditetapkan ke $ 0 dan tidak akan digunakan.
Chad Skeeters
3

Perintah dijalankan di setiap direktori yang berisi file yang cocok. Karena ctidak mengandung direktori, itu tidak cocok dan dengan demikian tidak akan dijalankan di sana.

Solusinya adalah menambahkan nama direktori ke argumen execdir, seperti:

find . -type d -execdir touch {}/foo \;
Jenny D
sumber
2

Dari man file

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

Direktori yang cocok Anda ctinggal di bdirektori sehingga dari situlah eksekutif dijalankan. Ini akan berfungsi seperti yang Anda harapkan jika Anda mencari file alih-alih direktori.

Anda mungkin dapat mencapai apa yang Anda inginkan dengan mengirimkan direktori xargskarena akan disediakan daftar lengkap direktori.

Mat
sumber