Dosya adındaki noktaların uzantı dışındaki alt çizgilerle değiştirilmesi


9

Birisi dosya adının nasıl yeniden adlandırılacağını önerebilir:

head.body.date.txt

Kime:

head_body_date.txt

Unix'te yeniden adlandırma yapmak için tek satırlık bir ifade var mı ?


9
Bunun .tar.gzbir uzantı olduğunu düşünüyor musunuz ? Ayrıca, U & L'ye hoş geldiniz!
EKons

2
Gerçekten Linux yerine Unix mi demek istediniz? Hangi Unix?
terdon

1
Açık cevap şu mv head.body.date.txt head_body_date.txt. Başka kısıtlamalarınız veya gerçek örnekleriniz varsa, lütfen sorunuzu bunlarla güncelleyin. Şu anda olduğu gibi, sorunun o açık ada sahip bir dosyaya mı, tüm dosyaların belirli bir biçime sahip olduğu tek bir dizine mi, yoksa belirli adlar için bir dizin hiyerarşisine bakmak ve bunları değiştirmek isteyip istemediğiniz belirsizdir.
Kusalananda

Yanıtlar:


9

Dosya adları üzerinde yineleme yapın ve dönüştürme için Parametre genişletmeyi kullanın:

for f in *.*.*.txt; do i="${f%.txt}"; echo mv -i -- "$f" "${i//./_}.txt"; done

Parametre genişletme deseni, dosya adındaki ( ) ${f//./_}tüm .s'yi s ile değiştirir ._$f

Yukarıdaki işlem, yeniden adlandırma işleminin gerçekleşmesine izin vermek için kuru bir çalışma yapacaktır echo:

for f in *.*.*.txt; do i="${f%.txt}"; mv -i -- "$f" "${i//./_}.txt"; done

Herhangi bir uzantıyla ilgilenmek istiyorsanız, yalnızca .txt:

for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
                     echo mv -i -- "$f" "${pre//./_}.${suf}"; done

echoGerçek işlem için kaldırmayı kontrol ettikten sonra :

for f in *.*.*.*; do pre="${f%.*}"; suf="${f##*.}"; \
                     mv -i -- "$f" "${pre//./_}.${suf}"; done

Genel, rastgele sayıda nokta için en az bir tane:

for f in *.*; do pre="${f%.*}"; suf="${f##*.}"; \
                 mv -i -- "$f" "${pre//./_}.${suf}"; done

keyfi sayıda nokta varsa genel bir yol var mı?
Ciprian Tomoiagă

1
@CiprianTomoiaga Yapmak:for f in *.*; do ...; done
heemayl

*.*Şimdi örnek sadece sabit sayıda nokta ile çalışır gibi görünüyor, çünkü desen düz örnek koyarak koyarak önerebilir .
ilkkachu

@ilkkachu Yeterince adil, düzenlendi.
heemayl

Çok teşekkürler heemay, benim için çalıştı. ve biraz öğrenme!
SG

4

ile perlesaslırename

$ rename -n 's/\.[^.]+$(*SKIP)(*F)|\./_/g' head.body.date.txt 
rename(head.body.date.txt, head_body_date.txt)
  • \.[^.]+$(*SKIP)(*F) bu kalıbı atla ve alternatif eşleşmeler ara
  • |\./_/gtümünü değiştir .ile_

Veya negatif ileriye doğru

$ rename -n 's/\.(?![^.]+$)/_/g' head.body.date.txt 
rename(head.body.date.txt, head_body_date.txt)

Bu tamam olduğunda, -nseçeneği kaldırın


3
rename 's/\.(?=[^.]*\.)/_/g' *.txt

.Dosya adındaki (yakalamayan önden okuma) son örneği dışında tümünü bulmak ve bunları değiştirmek için normal ifade değiştirmeyi kullanır _. *.*İsterseniz genelleştirir .

(Bu özel sürümü renameüzerinden yüklenir gibi görünüyor util-linux). Ben kullanıyorum Ubuntu 12.04(ağır tarih makinesinden, evet).


2

bash:

old=head.body.date.txt oldb=${old%.*} olde=${old##*.} ; \
mv -- "$old" "${oldb//./_}.${olde}"

(1) mv --Başlayan "eski" dosya adlarına karşı korunmak için kullanmalısınız -. (2) $oldKabuğa "$old"özel boşluklar veya karakterler içeren ( *ve gibi ?) “eski” dosya adlarına karşı korunmak için tırnak işareti ( ) koymalısınız . (3) Uzantının alt çizgi içerdiği patolojik durumda cevabınız başarısız oluyor: head.body.date.t_xtyeniden adlandırılıyor head_body_date_t.xt.
Scott

@Scott, teşekkürler. Kod, bahsedilen üç öğenin hepsine göre ayarlanmıştır.
agc

1

Kullanılması mv, sedve revtek satırda:

mv "head.body.date.txt" "$(echo head.body.date.txt | rev | sed 's/\./_/2g' | rev)"

txtGeçerli temsilcideki tüm dosyalara uygulamak istiyorsanız , globs kullanımı nasıl mvçalıştığından dolayı zor görünüyor , ancak bir forastarda bir döngü yapabilirsiniz :

for file in *.txt; do mv "$file" "$(echo $file | rev | sed 's/\./_/2g' | rev)"; done

Biraz daha uzun, ancak döngünüzdeki birkaç deseni eşleştirebilirsiniz!


2
(1) Arrghhh! Yapma $(ls …); sadece yap for file in *.txt. (2) Daha tırnak kullanmalıdır: mv "$file" "$(…)".
Scott

Teşekkürler Scott, usulüne uygun şekilde not edildi ve düzenlendi! Ben hala kabuğundaki bir gencim, lütfen nazik ol;)
Valentin B.

Gez, renamecevaplarında önerdikleri başkaları gibi kullanmak daha basit olsa da ...
Valentin B.

-1
 mv head.body.date.txt head_body_date.txt

Her seferinde tek bir dosya için olduğu kadar basittir. Bunun bir dizin içinde veya tüm dizinde yinelemeli olarak yapılmasını isteyip istemediğinizi belirtmezsiniz, bu en uygun, hızlı çözümünüz olacaktır.

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.