Dosyaları nasıl yeniden adlandırabilir ve karakterleri değiştirebilirim?


11

:Adında (iki nokta üst üste) bulunan bir grup dosyam var . (Tire) :ile değiştirmem gerekiyor -.

Bunu bir senaryoda yapmanın kolay bir yolu var mı?

Örnek Dosya Adı: 2013-10-11:11:52:08_055456663_045585_.txt

Yanıtlar:


17

Basit bir 1-astar yapmalıdır (Posix shuyumlu kabuk olduğunu varsayar ):

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

Açıklama:

  • for ... in ...; do ...; donebir döngü

  • *:* geçerli dizindeki :adında bulunan tüm dosya ve dizinlerle eşleşir

  • f döngüdeki her bir dosya adına sırayla atanır

  • mvilk argümanını ikincisine yeniden adlandırır; -v(ayrıntılı) yaptıklarını yazdırmasını ister; bu seçenek GNU-utils'e özgüdür, bu yüzden Linux'ta kullanılabilir, ancak Solaris'te mevcut değildir

  • $(...) kodu bir alt kabukta çalıştırır ve çıktıyı değiştirir

  • echo argümanını standart çıktıya yazdırır

  • tr standart çıktıyı okur ve verilen haritaya göre karakterleri çevirir

Eğer kullanıyorsanız bash , ekstra kabuk (yumurtlama önleyebilirsiniz $()alt süreçlerle) ( trdeğiştirerek) $(...)ile ${f//:/-}.


Basit bir çalışma cevabı için +1, ancak biraz daha fazla açıklama ile yapabilirdi. Örneğin for f in... döngü, geçerli dizindeki dosyaların eşleşmesi gereken tüm dosyalar üzerinde yinelenen bir döngüdür *:*. (Eşleşen dirslere ne olur?). Move komutu, bir kabuk çalıştırılarak yeni adın oluşturulduğu bir move oldname yeni adıdır $( subshell here ). Tr ne yapar ...
Hennes

@Hennes: Bu süper kullanıcı - gerçekten bu tür ayrıntılara girmem gerekiyor mu? Oh şey, işte
başlıyoruz

Hayır. Gerçek bir ihtiyaç olsaydı + 1'ed olmazdı. Ve ne yaptığını anlıyorum. Yine de diğer pek çok okuyucu için güzel olduğunu düşünüyorum.
Hennes

2
Sen yerini alabilir $(echo "$f" | tr ':' '-')ile "${f//:/-}"ve altkabuk, boru ve dış programı aramayı kaçının. Bence bu bir bashizm, ama ha. Buraya bakın .
evilsoup

@evilsoup Gerçekten; küçük veri kümeleri için fazla bir fark yaratmaz (ve biri okunabilirliği destekleyebilir), ancak böyle bir şeyin ne kadar hızlı toplandığına şaşıracaksınız. Son zamanlarda biraz ısırdım; iki basit dize masaj komutu artık gerekli olmayacak şekilde bir komut dosyasını yeniden yazmak, yürütme süresini kolayca % 90 veya daha fazla düşürür;
CVn

6

Başka bir gönderide belirttiğim gibi, renamearaç sizin için hile yapabilir. Sadece şunu yazmanız gerekir: rename s/:/-/ <files to rename> Bu, her iki noktayı sonunda adlandırdığınız tüm dosyalarda bir tire işareti ile değiştirir.2013-10-*

İşte diğer Yazıma bağlantı


1

Eminim bir UNIX pro bunu bash ile yapabilir, ama burada yakut ile hızlı ve kirli versiyonum.

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

path_to_files dosyasını yanlış adlandırılmış dosyalarınızın yoluna ayarlayın. Yukarıdaki kodu rename.rb adlı bir dosyaya kaydedin ve sonra:

username@machinename$ ruby rename.rb

@sds çok daha iyi bir cevap veriyor. Cevabımı silmeli miyim? Stackoverflow'da yeniyim.
shupru

1
Hayır; hala önemli bir değeri var. :)
Blacklight Parlayan

2
Bu cevap birkaç büyük downsides Ancak, var olabilecek alakalı olması ve kesinlikle hakkında bilinmeye değer. (Yine de yararlı olabilir, ancak uyarı emptor ve her şey.) Öncelikle, beyaz boşluklu dosya adlarıyla karşılaştığında (sadece klasik başarısızlık satırsonu değil) kötü bir şekilde kırılacak gibi görünüyor . Ayrıca, beyaz boşluk olmasa bile, dosya adlarındaki diğer özel karakterlerin kabuk tarafından işlenmesini önlemek için kabuk çağrısındaki dosya adını alıntılamalısınız (yine de Ruby'nin backtick operatörünün nasıl çalıştığını tam olarak bilmiyorum ).
CVn

1

Yalnızca bir veya birkaç dosyanız varsa, bu yeniden adlandırma işlemini sizin için yapabilir:

  1. Eğer bir değişken olarak hedef dosya adının desen Mağaza: p="201*".
  2. Mağaza eski dosya adını yeniden adlandırmak istiyorum: old_name=$(ls | grep $p).
  3. Mağaza Yeni bir dosya adı gerekli karakter değiştirmeler ile:

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

Bonus temizleme :
  a. Tekdüzelik uğruna çizgileri (-) iki nokta üst üste işaretleriyle (:) alt çizgi (_) ile değiştirmek istiyorsanız, bunu yapabilirsiniz:

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

  b. Son alt çizginin (hemen öncesinden .txt) da gitmesini istiyorsanız, new_namedeğişkeni şu şekilde ayarlayın :

    new_name=$(ls | grep $p | tr ':-' '_' | sed 's/_\./\./')
  1. Şimdi dosyanızı gerektiği gibi yeniden adlandırın: mv $old_name $new_name

         Not: mvYeniden adlandırma işleminde dosya adlarından herhangi birinin içinde bulunması durumunda başarısız olur spaces. Bu durumda, uygun değişkenleri tırnak içine alın, örneğin:
mv "$old_name" $new_name VEYA mv $old_name "$new_name" VEYA VEYA mv "$old_name" "$new_name"


Tek gömlekleri

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

0

renamer kullanarak :

$ renamer --find ":" --replace "-" *

Ben sadece dosyaları yeniden adlandırmak için tam bir node.js ortamı yüklemek biraz fazla olduğunu düşünüyorum. renamebirçok linux dağıtımına önceden kurulmuş bir araçtır. Ancak Windows için bu aracın harika olabileceğini düşünüyorum.
noggerl

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.