Skrip atau program Linux untuk mempersingkat nama file

8

Saya belum banyak berhasil menemukan namemangler versi Linux , yang saya perlukan untuk mengganti nama 1000 file sehingga dapat dibaca di Windows.

Adakah yang tahu tentang program Linux yang bisa melakukan ini?

Jika tidak, maka skrip mungkin berfungsi karena saya hanya perlu mengganti nama semua file dalam folder untuk, katakanlah, 16 karakter pertama. Saya menduga bahwa rute skrip mungkin layak turun tetapi tidak yakin harus mulai dari mana.

Grimlockz
sumber
2
Anda mungkin dapat menulis skrip Python atau Perl atau Ocaml atau Ruby dengan cepat.
Mengapa Anda tidak bisa menggunakan sistem file vfat saja, yang memungkinkan nama file panjang?
Berkumandang
2
Karena penasaran, berapa lama nama itu dan apa isinya sehingga tidak dikenali oleh Windows?
Bobby

Jawaban:

10

Pada Debian, Ubuntu dan turunannya, jika Anda masuk man renamepada prompt perintah, Anda akan mendapatkan halaman manual untuk utilitas penggantian nama yang memungkinkan perintah ekspresi reguler Perl-like yang sewenang-wenang untuk digunakan dalam penggantian nama.

Sebagai contoh, ini akan mempersingkat (dengan memotong) semua file dalam direktori saat ini menjadi lima:

rename 's/^(.{5}).*/$1/' *

Ini bekerja dengan menangkap lima karakter pertama kemudian menggunakannya dalam substitusi, menghilangkan sisanya.

Contoh lain adalah mempersingkat nama file (tanpa ekstensi) menjadi lima karakter sambil mempertahankan ekstensi:

rename 's/^(.{5}).*(\..*)$/$1$2/' *

Ini menangkap dua kelompok, yang pertama adalah lima karakter pertama, yang kedua adalah ekstensi. Ini akan berubah myCarefullyCraftedDocument.pdfmenjadi myCar.pdf.

Peringatan: Gunakan ini dengan hati-hati, lebih disukai pada salinan direktori Anda, atau dengan mengambil cadangan terlebih dahulu. Anda telah diperingatkan!! Minimal, gunakan rename -ndulu, yang akan menunjukkan kepada Anda apa yang akan dilakukan tanpa benar-benar melakukannya.


sumber
1
apakah ini akan menghilangkan awalan seperti dalam PDF? dan apa yang akan terjadi pada file dengan nama yang sama setelah dipersingkat?
Contoh khusus itu akan, ya. Anda dapat menulis regex untuk membiarkan ekstensi itu sendiri. Saya akan memperbarui jawabannya. Ini juga melindungi terhadap menimpa file yang sudah ada, jadi nanti nama akan gagal.
terima kasih atas bantuan Anda dalam hal ini - saya sangat berterima kasih. Saya punya satu masalah kecil jika beberapa pdf akan diganti namanya menjadi 5 katakanlah apa yang akan terjadi pada PDF itu mencoba untuk mengubah nama dengan nama yang sama? Apakah mereka cara kita bisa menambahkan nomor unik ke semua yang ada ini? lihat di bawah ini ename -n's / ^ (. {5}). * (\ .. *) $ / $ 1 $ 2 / '* Lampiran 123114345234525.pdf diganti namanya menjadi Annex.pdf Lampiran 123114432452352.pdf diganti nama menjadi Annex.pdf
@ Grimlockz, saya tidak berpikir Anda bisa memasukkan kecerdasan semacam itu ke dalam regex rename itu sendiri. Yang mungkin perlu Anda lakukan adalah menulis skrip untuk membungkus nama dengan jenis kecerdasan itu, dan itu lebih baik ditanyakan sebagai pertanyaan terpisah sehingga Anda akan mendapatkan lebih banyak orang merespons daripada hanya saya.
@ Grimlockz Inilah sebabnya mengapa Anda tidak ingin melakukan semuanya dalam regex. Anda akan lebih bahagia dan lebih baik menulis skrip yang menggunakan regex.
Spencer Rathbun
3

Anda dapat memindahkan file yang konflik ke direktori lain:

for i in *
do
    j=${i:0:16}

    if [ -e "$j" ]
    then
        mv "$i" /path/to/rename/later
    else
        mv "$i" "$j"
    fi
done
kev
sumber
1

Anda dapat menulis skrip untuk mempersingkat nama file dan menghapus karakter yang tidak disukai Windows dalam beberapa baris bash. Peringatan, kode yang belum diuji, diketik langsung ke browser saya.

shopt -s dotglob extglob
for x in *; do
  y=${x//+([!-!#$%&'().0-9@A-Z^_`a-z{}~])/_}  # change all problematic characters to _
  if [[ $y = .* ]]; then y=_${y#.}; fi        # change dot files to begin with _
  y=${y:0:16}                                 # truncate names
  y=${y,,}                                    # convert to lowercase
  if [[ -e $y || $y =~ ^(aux|clock\$|com[0-9]|con|lpt[0-9]|nul|prn)(\.*)?$ ]]; then
    # The file exists or is a DOS/Windows reserved name.
    # Change foo.bar to foo~1.bar, foo~2.bar, ... (I ignore the length restriction here)
    i=1
    if [[ $y =~ \. ]]; then
      prefix=${y%%.*}; suffix=.${y#*.}
    else
      prefix=$y; suffix=
    fi
    y=${prefix}~$i$suffix
    while [[ -e $y ]]; do
      ((++i))
      y=${prefix}~$i$suffix
    done
  fi
  mv -- "$x" "$y"
done

Jika Anda perlu mengulang ke dalam subdirektori, panggil skrip shell dari find -depth -exec …. Atau gunakan zsh sebagai ganti bash; di zsh, **/*(od)perluas ke semua file di bawah direktori saat ini, secara rekursif, dengan file yang bersarang lebih dalam terlebih dahulu.

Gilles 'SANGAT berhenti menjadi jahat'
sumber
1

Script shell / python / perl untuk hal semacam ini baik-baik saja, tetapi sepertinya aplikasi gui akan lebih baik untuk Anda, jadi saya akan merekomendasikan pyRenamer , yang dapat melakukan apa yang Anda inginkan, di antara banyak hal lain (operasi umum sederhana melalui preset [menghilangkan spasi, memotong nama file dari satu titik ke titik lain], pencarian / penggantian sederhana, regex yang rumit, previewer, dll).

Distribusi Anda bahkan mungkin memilikinya dalam repositori perangkat lunak mereka (Fedora tidak).

rsaw
sumber
0

Beberapa sistem tidak memiliki renameperintah, jadi sebagai alternatif untuk jawaban paxdiablo, berikut adalah cara melakukan hal yang sama dengannya mv.

for f in *.pdf; do 
    tmp=`echo $f | sed -r 's//^(.{5}).*(\..*)$/$1$2/'`
    mv -b ./"$f" ./"$tmp"
done

The -bbendera bergerak membuat cadangan file yang akan dihapus atau ditimpa. Dengan mengubah pola gumpalan pada for loop Anda dapat menyesuaikan file apa yang dijalankannya, menggunakan *dengan sendirinya untuk dijalankan pada semua file.

Spencer Rathbun
sumber
1
Tidak perlu menggunakan echodan pipa (bisa sangat mahal jika Anda memiliki banyak file), gunakan heredoc atau herestring sebagai gantinya.
Chris Down
1
@ ChrisDown lihat di sini . Menurut artikel wiki , proses perpipaan bercabang dua, tetapi tidak mengatakan apa-apa tentang menjalankannya di shell sendiri.
Spencer Rathbun
1
Misalnya, perhatikan perbedaan antara eval 'echo $BASH_SUBSHELL'dan eval 'echo $BASH_SUBSHELL' | cat.
Chris Down
2
Saya baru saja melakukan tes cepat, timemenggunakan loop echo $i | seddan menggunakan lagi sed ... <<<$i, dan herestring mengambil sekitar 2/3 waktu gema.
Kevin
1
@SpencerRathbun Ya. <<memulai <i> doc </i> di sini, yang multi-line dan membutuhkan pembatas. <<<membuat <i> string </i> di sini, yang hanya membutuhkan satu variabel / string. Cobalah var=abc // cat<<<$var // cat <<$var,.
Kevin
0

Jika Anda perlu bereksperimen dengan mengganti nama file dan kebetulan memiliki pustaka KDE diinstal pada sistem Anda (atau tidak keberatan menambahkannya), periksa krename.

Ini memungkinkan Anda untuk melakukan beberapa tugas penggantian nama sederhana secara langsung dengan alat-alatnya dan juga memungkinkan ekspresi reguler untuk situasi yang lebih rumit.

Ini menunjukkan kepada Anda pratinjau file berganti nama saat Anda membangun kondisi penggantian nama. Hal ini juga memungkinkan Anda untuk mengganti nama file yang sama lagi yang bermanfaat jika Anda ingin melakukan sesuatu yang rumit di mana melakukannya secara bertahap akan mengurangi kompleksitas setiap tahap menjadi sesuatu yang dapat Anda ketahui dengan cepat.

Joe
sumber
-1
for file in *; do
    mv "$file" $(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')
done &
Jairo Bernal
sumber