Bagaimana cara mengganti nama file dan mengganti karakter?

11

Saya memiliki sekelompok file yang memiliki :(titik dua) di dalam namanya. Saya perlu mengganti :dengan -(dash).

Apakah ada cara mudah untuk melakukan ini dalam naskah?

Contoh Nama File: 2013-10-11:11:52:08_055456663_045585_.txt

Ducky
sumber

Jawaban:

17

Seharusnya 1-liner sederhana (mengasumsikan shshell yang kompatibel dengan Posix ):

for f in *:*; do mv -v "$f" $(echo "$f" | tr ':' '-'); done

Penjelasan:

  • for ... in ...; do ...; doneadalah sebuah loop

  • *:* cocok dengan semua file dan direktori di direktori saat ini yang ada :di namanya

  • f ditugaskan pada gilirannya untuk masing-masing nama file dalam loop

  • mvmengganti nama argumen pertamanya menjadi argumen kedua; -v(verbose) memintanya untuk mencetak apa fungsinya; opsi ini khusus untuk GNU-utils , sehingga tersedia di Linux tetapi tidak untuk Solaris

  • $(...) mengeksekusi kode dalam sub-shell dan mengganti output

  • echo mencetak argumennya ke output standar

  • tr membaca output standar dan menerjemahkan karakter sesuai dengan peta yang disediakan

Jika Anda menggunakan bash , Anda dapat menghindari melahirkan shell tambahan ( $()) dengan sub-proses ( tr) dengan mengganti $(...)dengan ${f//:/-}.

sds
sumber
Memberi +1 untuk jawaban kerja yang sederhana, meskipun bisa dilakukan dengan penjelasan yang lebih banyak. Misalnya for f inloop ... adalah loop yang mengulang semua file dalam direktori saat ini di mana file harus cocok *:*. (Apa yang terjadi dengan dir yang cocok?). Perintah pindah adalah pindah nama lama dengan nama baru di mana nama baru dihasilkan dengan mengeksekusi shell dengan $( subshell here ). Apa yang dilakukan, ...
Hennes
@Hennes: ini superuser - saya benar-benar perlu untuk pergi ke jenis-jenis rincian? Oh well, ini dia ...
sds
Tidak. Jika ada kebutuhan nyata maka saya tidak akan memberi +1. Dan saya mengerti apa fungsinya. Saya pikir ini bagus untuk banyak pembaca lain.
Hennes
2
Anda dapat mengganti $(echo "$f" | tr ':' '-')dengan "${f//:/-}"dan menghindari panggilan subkulit, pipa, dan program eksternal. Saya pikir ini bashism, tapi eh. Lihat di sini .
evilsoup
@evilsoup Memang; itu tidak membuat banyak perbedaan untuk set data kecil (dan orang mungkin menyukai keterbacaan) tetapi Anda akan terkejut seberapa cepat sesuatu seperti itu bertambah. Saya mendapat sedikit dengan itu baru-baru ini; menulis ulang sebuah skrip sehingga dua perintah pemijatan string yang sederhana tidak lagi diperlukan, dengan mudah memangkas waktu eksekusi hingga 90% atau lebih, yang pada set data besar diterjemahkan ke beberapa menit waktu menjalankan wallclock.
CVn
6

Seperti yang dinyatakan dalam pos lain oleh saya renamealat ini bisa melakukan trik untuk Anda. Anda hanya perlu mengetik rename s/:/-/ <files to rename> ini menggantikan setiap titik dua dengan tanda hubung di semua file yang Anda beri nama di akhir, yaitu2013-10-*

Inilah tautan ke Posting saya yang lain

noggerl
sumber
1

Saya yakin pro UNIX bisa melakukan ini dengan bash, tapi inilah versi cepat dan kotor saya dengan ruby.

path_to_files = "/home/username/wrongnames/"
filenames = `ls #{path_to_files}`.split
filenames.each do |fn|
  `mv #{path_to_files + fn} #{path_to_files + fn.gsub(/:/, "-")}`
end

set path_to_files ke path ke file yang salah nama Anda. simpan kode di atas dalam file bernama rename.rb lalu:

username@machinename$ ruby rename.rb
Shupru
sumber
@ds memberikan jawaban yang jauh lebih baik. Haruskah saya menghapus jawaban saya? Saya baru di stackoverflow.
shupru
1
Tidak; masih memiliki nilai signifikan. :)
Blacklight Shining
2
Ada beberapa kelemahan utama dengan jawaban ini, namun, yang mungkin relevan dan pasti perlu diketahui. (Ini mungkin masih berguna, tetapi peringatan emptor dan semua itu.) Terutama, sepertinya itu akan rusak ketika menemukan nama file dengan spasi (bukan hanya baris kasus klasik kegagalan baru) di dalamnya. Juga, bahkan jika itu bukan untuk ruang putih, Anda harus mengutip nama file dalam doa shell untuk melindungi karakter khusus lainnya dalam nama file dari perlakuan oleh shell (meskipun saya tidak tahu persis bagaimana operator backtick Ruby bekerja ).
CVn
1

Jika Anda hanya memiliki satu atau beberapa file, ini dapat melakukan penggantian nama untuk Anda:

  1. Menyimpan pola nama file yang Anda targetkan sebagai variabel: p="201*".
  2. Menyimpan nama file lama Anda ingin mengubah nama: old_name=$(ls | grep $p).
  3. Simpan nama file baru dengan penggantian karakter yang diperlukan:

    new_name=$(ls | grep $p | sed 's/:/_/g')        # Using 'sed'
    
                OR
    
    new_name=$(ls | grep $p | tr ':' '_')           # Using 'tr'
    

Pembersihan bonus :
  a. Jika demi keseragaman Anda ingin mengganti tanda hubung (-) bersama titik dua (:) dengan garis bawah (_), Anda dapat melakukan ini:

    new_name=$(ls | grep $p | tr ':-' '_');

  b. Jika Anda ingin garis bawah terakhir (sesaat sebelum .txt) hilang, tetapkan new_namevariabel sebagai:

    new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./')
  1. Sekarang ganti nama file Anda sesuai kebutuhan: mv $old_name $new_name

         NB: mvakan gagal jika ada nama file dalam operasi penggantian nama yang ada spacesdi dalamnya. Dalam hal itu, bungkus variabel yang sesuai dalam tanda kutip, seperti:
mv "$old_name" $new_name ATAU mv $old_name "$new_name" ATAU mv "$old_name" "$new_name"


Satu kalimat

1a: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | sed 's/:/_/g'); mv $old_name $new_name

1b: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':' '_'); mv $old_name $new_name

2: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_'); mv $old_name $new_name

3: p="201*"; old_name=$(ls | grep $p); new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./'); mv $old_name $new_name
Dut A.
sumber
0

menggunakan renamer :

$ renamer --find ":" --replace "-" *
Lloyd
sumber
Saya pikir menginstal lingkungan node.js lengkap untuk hanya mengganti nama file agak terlalu banyak. renameadalah alat yang sudah diinstal pada banyak distribusi linux. Tapi saya pikir untuk Windows alat ini mungkin bagus.
noggerl
0

Ini mungkin berlebihan tetapi Anda dapat mengganti nama karakter khusus dengan skrip di tautan yang disediakan dalam jawaban ini:

/superuser//a/858671/365691

A.Danischewski
sumber