Jelaskan opsi -path dan -prune find

11

Saya memiliki skrip sederhana yang paling saya mengerti, itu adalah perintah find yang tidak jelas. Saya punya banyak dokumentasi tetapi tidak berfungsi untuk membuatnya lebih jelas. Pikiran saya adalah bahwa hal itu bekerja seperti untuk loop, file saat ini ditemukan swap dalam untuk {} dan disalin ke $ HOME / $ DIR_NAME, tapi bagaimana pencarian dengan -path dan -o -prune kerja? Sangat menjengkelkan untuk memiliki dokumentasi yang spesifik dan relevan seperti itu dan masih belum tahu apa yang terjadi.

#!/bin/bash
# The files will be search on from the user's home
# directory and can only be backed up to a directory
# within $HOME

read -p "Which file types do you want to backup " file_suffix
read -p "Which directory do you want to backup to " dir_name

# The next lines creates the directory if it does not exist
test -d $HOME/$dir_name || mkdir -m 700 $HOME/$dir_name

# The find command will copy files that match the
# search criteria ie .sh . The -path, -prune and -o
# options are to exclude the backdirectory from the
# backup.
find $HOME -path $HOME/$dir_name -prune -o \
-name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
exit 0

Ini hanya dokumentasi yang saya tahu saya harus dapat mengetahui hal ini.

pola -path

Nama file cocok dengan pola pola shell. Metakarakter tidak memperlakukan / atau . khususnya; jadi, misalnya, temukan. -path "./sr*sc" akan mencetak entri untuk direktori bernama ./src/misc (jika ada). Untuk mengabaikan seluruh pohon direktori, gunakan -prune daripada memeriksa setiap file di pohon. Sebagai contoh, untuk melewati direktori src / emacs dan semua file dan direktori di bawahnya, dan mencetak nama-nama file lain yang ditemukan, lakukan sesuatu seperti ini:

find . -path ./src/emacs -prune -o -print

Dari manual Findutils

- Tindakan: Perintah -exec; Varian tidak aman dari tindakan -execdir ini ditentukan oleh POSIX. Perbedaan utama adalah bahwa perintah dieksekusi dalam direktori dari mana ditemukan dipanggil, artinya {} diperluas ke jalur relatif dimulai dengan nama salah satu direktori awal, bukan hanya nama dasar dari file yang cocok.

Sementara beberapa implementasi find menggantikan {} hanya di mana ia muncul sendiri dalam argumen, GNU find menggantikan {} di mana pun itu muncul.

Dan

Sebagai contoh, untuk membandingkan setiap file header C di atau di bawah direktori saat ini dengan file / tmp / master:

      find . -name '*.h' -execdir diff -u '{}' /tmp/master ';'
Flerb
sumber
Saya pikir jika sesuatu itu merupakan duplikat dari find-path yang dijelaskan bahkan jika jawabannya di find: prune tidak mengabaikan path yang ditentukan memiliki jawaban yang tampaknya berlaku untuk pertanyaan ini. Mungkin jawaban yang dijelaskan menjelaskan cara masuk akal bagi seseorang yang lebih berpengalaman dalam penulisan skrip, tetapi itu tidak membantu saya. Sejauh ini jawaban yang ada di sini lebih masuk akal bagi saya, meskipun saya baru mulai melihat ke dalamnya.
Flerb

Jawaban:

23

-pathbekerja persis seperti -name, tetapi menerapkan pola ke seluruh pathname dari file yang diperiksa, bukan ke komponen terakhir.

-prune melarang turun di bawah file yang ditemukan, kalau-kalau itu adalah direktori.

Menyatukan semuanya, perintah

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;
  1. Mulai mencari file di $HOME.
  2. Jika ia menemukan file yang cocok, $HOME/$dir_namemaka file itu tidak akan berada di bawahnya ("memangkas" subdirektori).
  3. Kalau tidak ( -o) jika menemukan file yang cocok *$file_suffixmenyalinnya ke $HOME/$dir_name/.

Idenya tampaknya membuat cadangan dari beberapa isi $HOMEdalam subdirektori dari $HOME. Bagian-bagian dengan -prunejelas diperlukan untuk menghindari membuat cadangan cadangan ...

AlexP
sumber
Jika saya mengerti, maka: find akan mengulangi setiap direktori di $ HOME yang memiliki izin untuk masuk, kecuali $ HOME / $ dir_name, yang tidak akan turun ke dalamnya (karena tindakan prune akan mengevaluasi true dan the atau will tidak diambil), mencari file yang diakhiri dengan $ file_suffix. Kemudian segera setelah menemukannya, ia akan mengeksekusi cp "found_file.sh" menjadi $ HOME / $ dir_name? Juga, -path memungkinkan jalur ke file, dan berguna ketika Anda ingin menemukan direktori yang diturunkan dan tidak hanya bekerja di direktori saat ini?
Flerb
Pemahaman Anda hampir benar. -pathberfungsi seperti -name: memilih file. Perbedaannya adalah bahwa -namecocok dengan pola ke nama file, sedangkan -pathcocok dengan pola ke pathname lengkap. findselalu turun ke subdirektori, kecuali dicegah oleh -maxdepthatau -prunelain
AlexP
Oh! -path sedang diterapkan ke $ HOME / $ dir_name -prune maka, itu adalah urutan perintah yang mengacaukan saya, dan -path diperlukan untuk perintah prune karena harus sesuai dengan path lengkap dari direktori yang telah dipangkas.
Flerb
@ Darren Saya tidak yakin apakah itu cukup akurat. -path $HOME/$dir_nameadalah satu tindakan. Ini adalah tes yang memeriksa apakah jalur file yang sedang diperiksa cocok dengan apa pun $HOME/$dir_nameitu. -pruneadalah tindakan terpisah. Saya pikir kalimat pertama dari komentar pertama Anda secara akurat mencerminkan cara kerjanya.
David Z
Apakah ada sesuatu yang hilang untuk dilihat sebagai pipa? Saya bertukar-selesai dengan -print dan berpikir alirannya jelas sekarang: cari $ HOME | -path $ HOME / $ dir_name | -print
flerb
4

Ini adalah bagian dari perintah find, pernyataan -exec.

Ini memungkinkan Anda untuk berinteraksi dengan file / direktori yang ditemukan oleh findperintah.

find $HOME -path $HOME/$dir_name -prune -o -name "*$file_suffix" -exec cp {} $HOME/$dir_name/ \;

find $HOME berarti mencari file / direktori dalam $ HOME

Untuk memahami -path <some_path>, lihat `find -path` yang dijelaskan

Untuk memahami -prune, lihat /programming/1489277/how-to-use-prune-option-of-find-in-sh

-oberarti ATAU, jadi -path <some_path>ATAU-name *$file_suffix

-exec berarti menjalankan perintah.

cp {} $HOME/$dir_name/ salin semua file yang cocok dengan $HOME/$dir_name/

\;berarti mengakhiri -execperintah

sampah
sumber