Birden çok dosyayı yeniden adlandırmak için dosya adındaki dizeyi nasıl değiştirirsiniz? bu dize “#” içeriyor


42

https://serverfault.com/questions/70939/how-to-replace-a-text-string-in-multiple-files-in-linux

https://serverfault.com/questions/228733/how-to-rename-multiple-files-by-replacing-word-in-file-name

https://serverfault.com/questions/212153/replace-string-in-files-with-certain-file-extension

https://serverfault.com/questions/33158/searching-a-number-of-files-for-a-string-in-linux

Bu makalelerin tümü sorumu yanıtladı. Ancak hiçbiri benim için çalışmıyor. Bunun yerine değiştirmeye çalıştığım dizginin içinde # olduğundan dolayı şüpheleniyorum. Bunu çözmenin özel bir yolu var mı?

Bir site geçişi sırasında # U00a9 ile değiştirilen bir resim dosyasına sahibim. Bunlar şuna benziyor:

Lucky-#U00a9NBC-80x60.jpg
Lucky-#U00a9NBC-125x125.jpg
Lucky-#U00a9NBC-150x150.jpg
Lucky-#U00a9NBC-250x250.jpg
Lucky-#U00a9NBC-282x232.jpg
Lucky-#U00a9NBC-300x150.jpg
Lucky-#U00a9NBC-300x200.jpg
Lucky-#U00a9NBC-300x250.jpg
Lucky-#U00a9NBC-360x240.jpg
Lucky-#U00a9NBC-400x250.jpg
Lucky-#U00a9NBC-430x270.jpg
Lucky-#U00a9NBC-480x240.jpg
Lucky-#U00a9NBC-600x240.jpg
Lucky-#U00a9NBC-600x250.jpg
Lucky-#U00a9NBC.jpg

ve bunu şöyle bir şeye değiştirmek istiyorum:

Lucky-safeNBC-80x60.jpg
Lucky-safeNBC-125x125.jpg
Lucky-safeNBC-150x150.jpg
Lucky-safeNBC-250x250.jpg
Lucky-safeNBC-282x232.jpg
Lucky-safeNBC-300x150.jpg
Lucky-safeNBC-300x200.jpg
Lucky-safeNBC-300x250.jpg
Lucky-safeNBC-360x240.jpg
Lucky-safeNBC-400x250.jpg
Lucky-safeNBC-430x270.jpg
Lucky-safeNBC-480x240.jpg
Lucky-safeNBC-600x240.jpg
Lucky-safeNBC-600x250.jpg
Lucky-safeNBC.jpg

GÜNCELLEME:

Bu örneklerin hepsi "LU00a9ucky ile başlıyor, ancak burada farklı adlara sahip birçok resim var. Ben sadece" güvenli "ile değiştirilecek dizenin" # U00a9 "bölümünü hedefliyorum.


3
Peki gerçekte ne denedin? Birkaç soruya bağlandığınızı ve başarısız olduklarını söylediğinizi anlıyorum, ama nasıl başarısız oldu? IMO en iyi örnek renamekomutu kullanır . İsminin bu kadar basit olacağından şüpheleniyorum rename -n 's/#/safeNBC/' *.jpg.
— Zoredache

Denedim rename -n 's/#U00a9/safe/' *.jpgve komut kabul edildi, ancak değişiklik olmadı.

Elbette, kesinlikle incelediğiniz belgelerde görmüş olacağınız gibi -n, no actseçenek budur. Bu aslında kullanmadan önce çalışıp çalışmadığını görmenizi sağlar. Ekrandaki çıktı, potansiyel yeni adları doğru bir şekilde gösterdi mi?
— Zoredache

Özür dilerim, tüm dikkatinizi vermeden örneğinizi kopyalayıp yapıştırdım, -n olmadan yeniden adlandırma komutunu yaptım. @DTK'nin sorunu çözdüğüne inanıyorum, # ile kaçmıyordum.

MacOS'ta dosya isimlerindeki karakter dizileri: superuser.com/questions/152627/…
— Anton Tarasenko

Yanıtlar:


64

Değiştirmek için #tarafından somethingelsegeçerli dizine (özyinelemeli değil) kullanabilirsiniz içindeki bir dosya için GNU yeniden adlandırma programı:

rename  's/#/somethingelse/' *

Gibi karakterler -a ile kaçılmalıdır \.

Davanız için kullanmak istersiniz

rename 's/#U00a9/safe/g' *

Yalnızca belirli bir dosya seçiminde çalışmak istiyorsanız, örneğin sadece *.jpgbu seçimi eşleştirmek için son girdiyi ayarlayın:

rename 's/#U00a9/safe/g' *.jpg

Dosya adlarını değiştirmeden önce bir test yapmak için -nbayrağı kullanın :

demo/> ls                               
Lucky-#U00a9NBC-125x125.jpg  
Lucky-#U00a9NBC-150x150.jpg 

demo/> rename -n 's/#U00a9/safe/g' *.jpg
rename(Lucky-#U00a9NBC-125x125.jpg, Lucky-safeNBC-125x125.jpg)
rename(Lucky-#U00a9NBC-150x150.jpg, Lucky-safeNBC-150x150.jpg)

OS X için, GNU yeniden adlandırma homebrew : kullanılarak yüklenebilir brew install rename.


Bu benim makinemde işe yaramadı (Arch Linux), ama Mik'in cevabı yaptı.
— marcvangend

@ marcvangend Hangi sürümünü renamekullanıyorsunuz? # sudo pacman -S perl-renamedaha güçlü olan ve bu cevabın sizin için çalışmasını sağlamak için yeterli olabilecek perl sürümünü kuracak.
— John Gowers

@JohnGowers Teşekkürler! İki versiyon olduğunu bilmiyordum. Sistemimde rename --versiondöner, rename from util-linux 2.29.2öyle ki perl versiyonu değil.
— marcvangend

5
Yaygın olarak kullanılan iki renameyardımcı program vardır, ancak ikisi de GNU tarafından geliştirilmez: Debian tabanlı dağıtımlar rename, Perl paketleriyle bir yardımcı program içerirken, Red Hat tabanlı dağıtımlar Linux Çekirdeği Örgütü'ndeki renameyardımcı programı kullanır util-linux. Bağlantınız, GNU standart kütüphanesindeki renameC fonksiyonudur .
— Anthony G - Monica için adalet,

2
Bu cevap olarak, neden yazma zorundayız /giçinderename 's/#U00a9/safe/g' *
— Nikhil

21

dosyaların listesini bulun ve sonra anahtar kelimeyi değiştirin. aşağıda örnek

find . -name '*jpg' -exec bash -c ' mv $0 ${0/\#U00a9NBC/safeNBC}' {} \;

1
mv
— İsminde

Tüm dosyaları * _spec.rb yerine * _controller_spec.rb değiştirdim ve çözümünüz benim için işe yaradı. Teşekkürler.
— jedi

18

Bu zor değil, sadece ters eğik çizgi (\) hazırlayarak adındaki octothorpe (#) 'dan kaçtığınızdan emin olun.

find . -type f -name 'Lucky-*' | while read FILE ; do
    newfile="$(echo ${FILE} |sed -e 's/\\#U00a9/safe/')" ;
    mv "${FILE}" "${newfile}" ;
done 

Açıklaman #senin için ihtiyacım olan seslerden kaçmak mantıklı . Örnekte ters eğik çizgi göremiyorum. s/\#U00a9/safe/

@ LeonFrancisShelhamer iyi yakaladı. Ters eğik çizgiyi yuttu. Ben değiştireceğim.

17

Kabuktan kaçmak #için sadece tek tırnak ( '#'), çift tırnak ( "#") veya ters eğik çizgi ( \#) kullanın.

Durumunuzdaki en basit renamekomut (varsa) komutunu kullanmak olacaktır :

rename '#U00a9' safe *.jpg

2
Teşekkürler. En yüksek oyu alan cevap ( rename 's/#/somethingelse/' *) makinemde işe yaramadıysa (Arch Linux).
— marcvangend

1
Bu util-linux'taki rename komutunu kullanarak çalışır.
— 14'te imclean

10

Sed içinde nasıl emin değilim, ancak bunu bir bash kabuğunda deneyebilirsiniz:

for f in Lucky-#U00a9NBC-*.jpg; do mv -v "$f" "${f/#U00a9/safe}"; done;

açıklama:

  1. glob ile eşleşen tüm dosya isimleri arasında dolaşıyor (Lucky- # U00a9NBC - *. jpg)
  2. move komutunu (mv) kullanarak dosyayı yeniden adlandırır
  3. yeni adı oluşturmak için yerel bash parametresinin yerine $ {var / Pattern / Değiştirme} kullanır ("$ {f / # U00a9 / safe}")

Parametre değiştirme hakkında daha fazla bilgi (ki bunlar IMO'nun yeterince kullanılmaması): http://www.tldp.org/LDP/abs/html/parameter-substitution.html


Bu kod soruyu cevaplayabilse de, kendi başına çok kullanışlı değil. Sorunun nasıl çözüldüğünü açıklamak , cevabın yararlılığını ve uzun vadeli değerini artırabilir.
— Anthony G - Monica

Anthony'nin yorumuna göre adım adım açıklama ve daha fazla okuma eklendi.
— Gregory Patmore

1

Yukarıdaki örnekler sistemimde çalışmıyordu (CentOS 5.6), bu yüzden çalışan bir (muhtemelen daha fazla sisteme özgü) komutu buldum (not: \komut satırında '#' ile kaçmanız gerekir ):

rename \#U00a9 safe *.jpg

[Ayrıca: Henüz yorum yapacak kadar itibarımız yok, bu yüzden Nikhil'in 'in' /gin kullanımıyla ilgili rename 's/old_string/new_string/g'sorusuna cevaben (yukarıdaki başka bir cevap için yapılan yorumlarda belirtilmiştir):

g'Global' bir ikame yapmak için değiştiriciyi kullanın (yani, old_string yerine new_string yerine new_string yerine). Cevabımda bu gerekli olmamalı, çünkü renamebelirtilen tüm dosyalara uygulanacak *. Bkz https://www.computerhope.com/unix/rename.htm bu ve diğer düzenleyiciler bir özlü açıklama için.]


Doğru; CentOS gibi Fedora türetilmiş işletim sistemlerinde renameDebian türetilmiş işletim sistemlerinden farklı bir sürüm var . Bkz unix.stackexchange.com/a/238862/135943 . Bu arada, CentOS 5.6 oldukça eski ve yükseltmenizi tavsiye ederim.
— Wildcard

Ah, açıklama + bağlantı için teşekkürler. Eski işletim sistemi iş başında ve bu yüzden yükseltme yapmak bana kalmadı :) ama yeni bir küme inşa ediliyor ve büyük olasılıkla ilerlerken muhtemelen yükseleceğiz ...
— Ezra Citron

0

İşte DTK'nın yeniden kullanılabilir bash fonksiyonuna sarılmış çözümü:

function renameFilesRecursively () {

  SEARCH_PATH="$1"
  SEARCH="$2"
  REPLACE="$3"

  find ${SEARCH_PATH} -type f -name "*${SEARCH}*" | while read FILENAME ; do
      NEW_FILENAME="$(echo ${FILENAME} | sed -e "s/${SEARCH}/${REPLACE}/g")";
      mv "${FILENAME}" "${NEW_FILENAME}";
  done

}

İşte nasıl kullanabilirsiniz:

renameFilesRecursively /home/user/my-files apple orange

0

Aslında renametam olarak aranan --substveya -skısaca bir seçenek var . Regex sözdizimini kullanmanıza gerek yok.

rename -s '#U00a9' 'safe' *

Çoklu oluşumları değiştirmek / yerine koymak istiyorsanız, --subst-allveya tuşlarını kullanın -S.

BTW, sadece iyi biz de bunun için bir seçenek var ... hiçbir şey (dosya adı çıkarın) tarafından bir dize yerine istedi -d/--deleteve -D/--delete-all:

rename -d '#U00a9' *

-1

Diğer bir seçenek ise pyRenamer, özellikle toplu yeniden adlandırma için yapılmış bir uygulamayı kullanmaktır .

İle yüklenebilir sudo apt-get install pyrenamer

Kullanım ayrıntıları için GitHub'daki README dosyasına bakın .


1
Bunun gerçekten soruyu cevaplayabileceğini düşünüyorsanız, lütfen cevabınıza bir açıklama ekleyin. Kendisi, sadece bir paket yükler. Komutun ne yaptığını açıklamalı ve OP'nin özel gereksinimini karşılayan bir örnek vermelisiniz.
— roaima,
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.