Berikut ini adalah perbaikan langsung dari pendekatan Anda:
find . -type f -name 'file*' -exec sh -c 'x="{}"; mv "$x" "${x}_renamed"' \;
Namun, ini sangat mahal jika Anda memiliki banyak file yang cocok, karena Anda memulai shell baru (yang mengeksekusi a mv
) untuk setiap pertandingan. Dan jika Anda memiliki karakter lucu dalam nama file apa pun, ini akan meledak. Pendekatan yang lebih efisien dan aman adalah ini:
find . -type f -name 'file*' -print0 | xargs --null -I{} mv {} {}_renamed
Ini juga memiliki keuntungan bekerja dengan file yang anehnya bernama. Jika find
mendukungnya, ini dapat dikurangi menjadi
find . -type f -name 'file*' -exec mv {} {}_renamed \;
The xargs
Versi ini berguna bila tidak menggunakan {}
, seperti di
find .... -print0 | xargs --null rm
Di sini rm
dipanggil sekali (atau dengan banyak file beberapa kali), tetapi tidak untuk setiap file.
Saya menghapus basename
pertanyaan Anda, karena mungkin salah: Anda akan pindah foo/bar/file8
ke file8_renamed
, bukan foo/bar/file8_renamed
.
Suntingan (seperti yang disarankan dalam komentar):
- Ditambahkan pendek
find
tanpaxargs
- Menambahkan stiker keamanan
x
ini tidak berguna:find . -type f -name 'file*' -exec mv {} "{}_renamed" \;
xargs
versi memiliki efisiensi yang sama seperti contoh pertama /x
ada hanya untuk memperbaiki secara langsung pendekatan si penanya.{}
secara langsung dalam perintah shell (sh -c "…"
) - Anda harus selalu menyampaikannya sebagai argumen. (2) Tidak semua versifind
mendukung{}_renamed
konstruk. (3) Saya tidak mengerti pernyataan Anda yangxargs
berguna untuk menghapus file (berbeda dengan mengganti nama mereka).xargs
bukanmv
vsrm
, tetapi penggunaan{}
vs tanpa. Yang pertama mirip denganmv file1 file1_renamed; mv file2 file2_renamed
yang keduarm file1 file2
.Setelah mencoba jawaban pertama dan mempermainkannya sedikit saya menemukan bahwa itu bisa dilakukan sedikit lebih pendek dan kurang rumit menggunakan
-execdir
:Sepertinya itu juga harus melakukan apa yang Anda butuhkan.
sumber
find
implementasi yang mendukung-execdir
dan{}
tidak secara keseluruhan, itu juga yang paling aman. Anda mungkin ingin menambahkan a-i
tomv
(dan-T
jika Andamv
mendukungnya)mv
untuk meminta, atau selain itu, Anda dapat (tidak diragukan tergantung pada apakah implementasi Andafind
mendukungnya) juga menggunakan-okdir
yang akan menampilkan perintah yang akan dieksekusi sebelum menjalankannya.-depth
juga merupakan ide bagus jika Anda juga akan menyentuh nama direktori.-execdir
memang memiliki satu kelemahan yang sangat menjengkelkan,find
menolak untuk melakukan apa pun jikaPATH
mengandung jalur relatif ... askubuntu.com/questions/621132/…find: The relative path XXX is included in the PATH environment
Pendekatan lain adalah dengan menggunakan
while read
loop overfind
output. Hal ini memungkinkan akses ke setiap nama file sebagai variabel yang dapat dimanipulasi tanpa harus khawatir tentang biaya / potensi masalah keamanan tambahan pemijahan terpisahsh -c
proses menggunakanfind
's-exec
pilihan.Dan jika shell yang digunakan mendukung
-d
opsi untuk menentukanread
pembatas, Anda dapat mendukung file dengan nama yang aneh (misalnya dengan baris baru) menggunakan yang berikut:sumber
Saya ingin memperluas pada jawaban pertama dan perhatikan bahwa ini tidak akan berfungsi untuk menambahkan ke nama file karena
./
awalan path hadir dalam argumen nama file.Memodifikasi jawaban Thomas Erker, saya menemukan ini pendekatan yang lebih umum
opsi xargs:
--null
Menunjukkan bahwa setiap argumen yang melewatistdin
diakhiri dengan karakter nol (\0
). Dengan cara ini nama file dapat berisi spasi, jika tidak setiap kata akan dimasukkan sebagai parameter yang berbeda untukmv
perintah.-I replace-str
Setiap arusreplace-str
akan diganti dengan argumen yang dibacastdin
. Jadi, Anda dapat mengubahnya untuk string lain jika Anda membutuhkannya.sumber
pringf "%f\0"
ganti aprint0
?-print0
akan menghasilkan./
awalan jikaPATTERN
berisi karakter meta shell yang menghalangi ketika mengganti nama menjadi sesuatu yang awalan nama aslinya. (mis. ganti nama0 - foo.txt
menjadi00 - foo.txt
,1 - bar.txt
ke01 - bar.txt
dll.)Saya bisa melakukan sesuatu yang mirip dengan
for
,find
, danmv
.Ini menemukan semua
config.yml
file dan menamainya kembaliconfig.yml.bak
sumber
for
dan melakukan operasi massal.