Bagaimana Bash bisa mengganti nama serangkaian paket untuk menghapus nomor versinya? Saya telah bermain-main dengan keduanya expr
dan %%
, tidak berhasil.
Contoh:
Xft2-2.1.13.pkg
menjadi Xft2.pkg
jasper-1.900.1.pkg
menjadi jasper.pkg
xorg-libXrandr-1.2.3.pkg
menjadi xorg-libXrandr.pkg
bash
shell
file-rename
Jeremy L.
sumber
sumber
Jawaban:
Anda dapat menggunakan fitur perluasan parameter bash
Kutipan diperlukan untuk nama file dengan spasi.
sumber
rename "s/-[0-9.]*//" *.pkg
Jika semua file berada di direktori yang sama, urutannya
akan melakukan pekerjaanmu. The sed perintah akan membuat urutan dari mv perintah, yang kemudian dapat pipa ke shell. Sebaiknya jalankan pipeline terlebih dahulu tanpa trailing
| sh
untuk memverifikasi bahwa perintah tersebut melakukan apa yang Anda inginkan.Untuk mengulang melalui beberapa direktori, gunakan sesuatu seperti
Perhatikan bahwa dalam sed , urutan pengelompokan ekspresi reguler adalah tanda kurung yang diawali dengan garis miring terbalik,
\(
dan\)
, bukan tanda kurung tunggal(
dan)
.sumber
ls
dalam skrip. Variasi pertama dapat dicapai denganprintf '%s\n' * | sed ...
dan dengan beberapa kreativitas Anda mungkin dapat menyingkirkannyased
juga. Bash'sprintf
menawarkan'%q'
kode format yang bisa berguna jika Anda memiliki nama file yang berisi metakarakter shell literal.Saya akan melakukan sesuatu seperti ini:
seharusnya semua file Anda ada di direktori saat ini. Jika tidak, coba gunakan temukan seperti yang disarankan di atas oleh Javier.
EDIT : Juga, versi ini tidak menggunakan fitur khusus bash, seperti yang lain di atas, yang membuat Anda lebih mudah dibawa.
sumber
Berikut adalah POSIX yang hampir setara dengan jawaban yang diterima saat ini . Ini memperdagangkan
${variable/substring/replacement}
perluasan parameter khusus Bash dengan yang tersedia di shell yang kompatibel dengan Bourne.Perluasan parameter
${variable%pattern}
menghasilkan nilaivariable
dengan sufiks apa pun yang cocokpattern
dihapus. (Ada juga${variable#pattern}
untuk menghapus awalan.)Saya menyimpan subpola
-[0-9.]*
dari jawaban yang diterima meskipun mungkin menyesatkan. Ini bukan ekspresi reguler, tapi pola glob; jadi ini tidak berarti "tanda hubung yang diikuti oleh nol atau lebih angka atau titik". Sebaliknya, itu berarti "tanda hubung, diikuti dengan angka atau titik, diikuti oleh apa saja". "Apa saja" akan menjadi pertandingan yang sesingkat mungkin, bukan yang terpanjang. (Bash menawarkan##
dan%%
untuk memotong awalan atau sufiks terpanjang, bukan yang terpendek.)sumber
Kami dapat berasumsi
sed
tersedia di * nix apa pun, tetapi kami tidak dapat memastikan itu akan mendukungsed -n
untuk menghasilkan perintah mv. ( CATATAN: Hanya GNU yangsed
melakukan ini.)Meski begitu, bash builtins dan sed, kita dapat dengan cepat menyiapkan fungsi shell untuk melakukan ini.
Pemakaian
Membuat folder target:
Karena
mv
tidak secara otomatis membuat folder target, kami tidak dapat menggunakan versi awal kamisedrename
.Ini adalah perubahan yang cukup kecil, jadi akan menyenangkan untuk menyertakan fitur itu:
Kita memerlukan fungsi utilitas,
abspath
(atau jalur absolut) karena bash tidak memiliki build ini.Setelah kita memilikinya, kita dapat menghasilkan folder target untuk pola sed / rename yang menyertakan struktur folder baru.
Ini akan memastikan kami mengetahui nama folder target kami. Saat kami mengganti nama, kami harus menggunakannya pada nama file target.
Inilah skrip sadar folder lengkap ...
Tentu saja, ini masih berfungsi ketika kami tidak memiliki folder target tertentu juga.
Jika kami ingin memasukkan semua lagu ke dalam folder,
./Beethoven/
kami dapat melakukan ini:Pemakaian
Putaran bonus ...
Menggunakan skrip ini untuk memindahkan file dari folder ke dalam satu folder:
Dengan asumsi kami ingin mengumpulkan semua file yang cocok, dan menempatkannya di folder saat ini, kami dapat melakukannya:
Perhatikan pola sed regex
Aturan pola sed reguler berlaku dalam skrip ini, pola ini bukan PCRE (Perl Compatible Regular Expressions). Anda bisa saja memperluas sintaks ekspresi reguler, menggunakan salah satu
sed -r
ataused -E
bergantung pada platform Anda.Lihat kepatuhan POSIX
man re_format
untuk penjelasan lengkap tentang pola regexp dasar sed dan diperpanjang.sumber
Saya menemukan bahwa mengganti nama adalah alat yang jauh lebih mudah digunakan untuk hal semacam ini. Saya menemukannya di Homebrew untuk OSX
Sebagai contoh Anda, saya akan melakukan:
'S' berarti pengganti. Bentuknya adalah s / searchPattern / replacement / files_to_apply. Anda perlu menggunakan regex untuk ini yang membutuhkan sedikit studi tetapi itu sepadan dengan usaha.
sumber
for
dansed
lain - lain boleh-boleh saja, tetapi jauh lebih sederhana dan lebih cepat untuk digunakanrename
jika Anda sering melakukannya.rename
perintah; di samping itu, beberapa akan memiliki yang berbedarename
perintah dengan fitur yang berbeda, sintaks, dan / atau pilihan. Ini terlihat seperti Perlrename
yang cukup populer; tetapi jawabannya harus benar-benar menjelaskan hal ini.lebih baik digunakan
sed
untuk ini, seperti:mencari ekspresi reguler dibiarkan sebagai latihan (seperti berurusan dengan nama file yang menyertakan spasi)
sumber
Ini tampaknya bekerja dengan asumsi itu
lepas .pkg, lalu lepas - ..
sumber
-e
. Missed -e 's/\.pkg//g' -e 's/-.*//g'
.ls
output dan mengutip variabel Anda. Lihat juga shellcheck.net untuk mendiagnosis masalah umum dan antipattern dalam skrip shell.Saya memiliki beberapa
*.txt
file untuk diubah namanya seperti.sql
di folder yang sama. di bawah ini berhasil untuk saya:sumber
Terima kasih atas jawaban ini. Saya juga punya masalah. Memindahkan file .nzb.queued ke file .nzb. Itu memiliki spasi dan cruft lain di nama file dan ini memecahkan masalah saya:
Ini berdasarkan jawaban Diomidis Spinellis.
Regex membuat satu grup untuk seluruh nama file, dan satu grup untuk bagian sebelum .nzb.queued dan kemudian membuat perintah pemindahan shell. Dengan senar yang dikutip. Ini juga menghindari pembuatan loop dalam skrip shell karena ini sudah dilakukan oleh sed.
sumber
-n
opsi dengan cara yang sama.