Bagaimana cara menggunakan `find -exec` untuk menjalankan perintah dalam direktori file yang ditemukan (bukan direktori saat ini)?

15

Katakanlah saya sedang dalam direktori yang memiliki beberapa subdirektori, dir1, dir2, dan dir3. Masing-masing direktori memiliki file foodan saya ingin menjalankan perintah yang sama pada masing foo-masing direktori dan memiliki perintah yang dieksekusi dari dalam direktori itu.

Jika saya melakukannya "dengan tangan", itu akan terlihat seperti ini:

cd dir1
(execute on foo)
cd ../dir2
(execute on foo)
cd ../dir3
(execute on foo)

Sangat penting bahwa perintah dijalankan dari masing-masing direktori . fooadalah skrip penjadwalan batch (untuk HTCondor, jika Anda ingin tahu) dan harus dijalankan dari setiap subdirektori sehingga output dari proses yang dimulai oleh skrip penjadwalan akan berakhir di setiap subdirektori.

Pertanyaan " Temukan file dan jalankan perintah di direktori file ", sejauh yang saya tahu, tidak menjawab pertanyaan saya. Jawaban pertama untuk pertanyaan itu lebih merupakan solusi yang tidak akan berfungsi dalam kasus saya, dan jawaban kedua tidak memiliki cukup penjelasan bagi saya untuk mengetahui cara menggunakannya.

Bintang neutron
sumber
@roaima, tolong jelaskan bagaimana itu duplikat. Jawaban pertama dari pertanyaan itu tidak membantu saya, ini lebih merupakan suatu penyelesaian, dan jawaban kedua tidak masuk akal bagi saya. Perlu penjelasan lebih lanjut agar saya tahu cara menggunakannya.
NeutronStar

Jawaban:

23

Dengan asumsi Anda findmendukungnya, gunakan -execdiropsi sebagai ganti-exec

find * -name 'foo' -execdir pwd \;

Jika tidak, berikan detail platform dan / atau distribusi Anda (sebagaimana diperlukan).

roaima
sumber
Ketika Anda mulai menekan "find: Path relatif './node_modules/.bin' termasuk dalam variabel lingkungan PATH,": askubuntu.com/questions/621132/…
Ciro Santilli 冠状 病毒 审查 六四 事件 事件 法轮功 法轮功
Maaf jika saya boleh menulis seperti itu, tetapi -execdir (di Ubuntu) adalah omong kosong, karena itu tidak memberi Anda {}, tetapi orang tua dari {}.
uav
1
@uav tanpa mengetahui kasus penggunaan Anda, saya tidak dapat membantu Anda. Tetapi sebagai tanggapan atas keluhan Anda, dokumentasi dengan jelas menyatakan " Suka -exec, tetapi perintah yang ditentukan dijalankan dari subdirektori yang berisi file yang cocok ".
roaima
Ya, benar, ini kasus khusus jika Anda mencari -type d (= direktori) dan kemudian sub-optimal.
uav
Tanpa mengetahui kasus penggunaan Anda, saya tidak dapat membantu Anda.
roaima
4

Dengan asumsi Anda tahu persis direktori apa yang menjalankan perintah Anda,

for dir in dir1 dir2 dir3; do
    ( cd "$dir" && somecommand foo )
done

atau, mengulangi foofile,

for foo in */foo; do
  ( cd "${foo%/*}" && somecommand foo )
done

Subshell mencegah cduntuk mempengaruhi direktori kerja dari sisa skrip. The ${foo%/*}substitusi parameter mengembang dengan nama direktori dimana foofile yang hidup (dengan menghapus semuanya setelah yang terakhir /dalam nilai $foo).

Menggunakan standar finduntuk melakukan hal yang sama (dalam kasus di mana foofile dapat hidup jauh di dalam struktur direktori):

find . -type f -name foo -exec sh -c '
    for foo do
        ( cd "${foo%/*}" && somecommand foo )
    done' sh {} +

Dengan kata lain: Temukan semua file biasa yang disebut "foo" di mana saja di direktori saat ini atau di bawah dan berikan nama path mereka ke skrip shell ini dalam batch. Script shell akan mengulangi nama path yang diberikan, mengubah direktori ke bagian direktori dari setiap pathname dan jika itu berhasil, jalankan somecommand foo.

Untuk solusi yang menggunakan yang tidak standar -execdir, lihat jawaban roaima . Jawabannya disesuaikan dengan contoh saya:

find . -type f -name foo -execdir somecommand foo ';'
Kusalananda
sumber