Jawaban:
Sunting: Sementara jawaban berikut menjelaskan kasus penggunaan umum, saya harus mencatat bahwa menghapus file dan direktori adalah kasus khusus. Alih-alih menggunakan -execdir rm {} \;
konstruk, cukup gunakan -delete
, seperti pada:
find -iname '*.txt' -delete
Ini menangani banyak kasus tepi yang mungkin tidak Anda pikirkan termasuk file pesanan dan direktori apa yang perlu dihapus agar tidak mengalami kesalahan. Untuk kasus penggunaan lainnya ...
Cara terbaik untuk menangani perintah yang sedang berjalan dari hasil find biasanya menggunakan berbagai -exec
opsi pada find
perintah. Khususnya Anda harus mencoba untuk menggunakan -execdir
kapan pun dimungkinkan karena ia berjalan di dalam direktori file yang ditemukan dan umumnya lebih aman (dalam arti mencegah kesalahan bodoh menjadi bencana) daripada opsi lain.
The -exec
pilihan diikuti oleh perintah Anda ingin menjalankan dengan {}
yang menunjukkan tempat di mana file ditemukan oleh find harus dimasukkan dan diakhiri oleh salah satu \;
untuk menjalankan perintah sekali untuk setiap file atau +
mengganti {}
dengan daftar argumen dari semua pertandingan . Perhatikan bahwa terminator titik koma diloloskan sehingga tidak dipahami oleh shell sebagai pemisah yang mengarah ke perintah baru.
Katakanlah Anda menemukan semua file teks:
find -iname '*.txt' -execdir rm {} \;
Berikut ini bit yang relevan dari manual find ( man find
):
-exec command ;
Execute command; true if 0 status is returned. All following
arguments to find are taken to be arguments to the command until
an argument consisting of ‘;’ is encountered. The string ‘{}’
is replaced by the current file name being processed everywhere
it occurs in the arguments to the command, not just in arguments
where it is alone, as in some versions of find. Both of these
constructions might need to be escaped (with a ‘\’) or quoted to
protect them from expansion by the shell. See the EXAMPLES sec-
tion for examples of the use of the -exec option. The specified
command is run once for each matched file. The command is exe-
cuted in the starting directory. There are unavoidable secu-
rity problems surrounding use of the -exec action; you should
use the -execdir option instead.
-exec command {} +
This variant of the -exec action runs the specified command on
the selected files, but the command line is built by appending
each selected file name at the end; the total number of invoca-
tions of the command will be much less than the number of
matched files. The command line is built in much the same way
that xargs builds its command lines. Only one instance of ‘{}’
is allowed within the command. The command is executed in the
starting directory.
-execdir command ;
-execdir command {} +
Like -exec, but the specified command is run from the subdirec-
tory containing the matched file, which is not normally the
directory in which you started find. This a much more secure
method for invoking commands, as it avoids race conditions dur-
ing resolution of the paths to the matched files. As with the
-exec action, the ‘+’ form of -execdir will build a command line
to process more than one matched file, but any given invocation
of command will only list files that exist in the same subdirec-
tory. If you use this option, you must ensure that your $PATH
environment variable does not reference ‘.’; otherwise, an
attacker can run any commands they like by leaving an appropri-
ately-named file in a directory in which you will run -execdir.
The same applies to having entries in $PATH which are empty or
which are not absolute directory names.
Alternatifnya adalah menyalurkan output dan menguraikannya dengan perintah berikutnya. Satu-satunya cara aman untuk melakukannya adalah dengan menggunakan -print0
opsi, yang memberitahu find
untuk menggunakan karakter nol sebagai pembatas hasil. Perintah yang menerima harus memiliki kemampuan untuk mengenali input yang dibatasi nol. Contoh:
find /home/phunehehe -iregex '.*\.png$' -print0 | xargs -0 file
Perhatikan bahwa -0
opsi memberi tahu xargs
untuk memperlakukan input sebagai nol dibatasi.
-exec
dengan lebih banyak file jika Anda mengakhirinya dengan +
alih - alih ;
. Lihat jawaban caleb.
Saya sedang mencari jawaban untuk ini dan saya menemukan utas ini. Jawabannya memberi saya dan gagasan tentang bagaimana saya bisa mencapainya. Misalkan Anda ingin menemukan mediainfo
semua file JPEG
Ini akan ditambahkan mediainfo "
di awal dan "
di akhir setiap file yang cocok (Untuk menghindari karakter khusus sebanyak mungkin), taruh ke skrip dan jalankan skrip:
find . -name *.jpg | sed -e 's/^/mediainfo "/g;' | sed -e 's/$/"/g;' > foo.sh && sh foo.sh
Jika Anda khawatir ada sesuatu yang salah, Anda dapat melewatkan mengarahkan ulang output ke file dan hanya melihat hasilnya di terminal sebelum menjalankan skrip.
Anda dapat melakukannya dengan menggunakan xargs
perintah. xargs
pada dasarnya menjalankan perintah sekali untuk setiap instruksi dari input standarnya. Jadi, jika Anda perlu menghapus semua .jpg
file dalam direktori misalnya, cara cepat pada baris perintah adalah:
$ find ./ -name "*.jpg" | xargs rm
Anda juga dapat menggunakan backtick (di atas tombol Tab) untuk melakukan ini (perhatikan bahwa ini adalah karakter backquote, bukan karakter kutipan tunggal):
$ rm `find ./ -name "*.jpg"`
Perhatikan bahwa karena cara xargs
dan shell memproses inputnya, metode xargs hanya berfungsi jika tidak ada nama file dan nama direktori yang terlibat mengandung spasi putih atau salah satu dari \"'
; metode backquote hanya berfungsi jika tidak ada nama file dan nama direktori yang terlibat mengandung spasi putih atau salah \[?*
.
find
, yang -exec
umumnya merupakan solusi yang lebih baik. Jika Anda ingin menentukan ini sebagai alternatif, setidaknya jelaskan bagaimana cara menggunakan find -print0 | xargs -0
penanganan pemutusan nama file yang aman dan jelaskan kapan harus berhati-hati tentang backticks.