Bash komut dosyasını kullanarak katların dosyalarını yeniden adlandırma


27

Bash komut dosyası kullanarak aynı dizindeki birden fazla dosyayı yeniden adlandırmak istiyorum. Dosyaların isimleri aşağıdaki gibidir:

file2602201409853.p
file0901201437404.p  
file0901201438761.p  
file1003201410069.p  
file2602201410180.p

Aşağıdaki biçimde yeniden adlandırmak istiyorum:

file2503201409853.p
file2503201437404.p  
file2503201438761.p  
file2503201410069.p  
file2503201410180.p

Rename komutu hakkında okuyordum ve bu şekilde yapmaya çalışıyorum, fakat hiçbir şey yapmıyor, sanırım sözdizimi hakkında sorularım var. Sonra mv komutunu kullanarak şöyle bir döngü yapabileceğinizi okudum :

for file in cmpsms*2014*.p; do
    mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}"
done

Ancak dosyaları yeniden adlandıramıyorum. Neyi yanlış yapıyorum?



2
Bir parametre genişletme değiştirme ifadesinin sağ tarafında bir desen ifadesine sahip olamazsınız. Onun nerede olmasını bekliyordun *?
kojiro

@Kiwy Bu soru, dosya adının bir kısmını silmeyle ilgilidir. Ergo, şüpheyle çoğaltıyor.
CVn

2
Bir dahaki sefere, lütfen yapmak istediğiniz dosya adı değişikliklerini açıklayın (farkları ve benzerlikleri görmeden önce adil bir şekilde bakmak zorunda kaldım). Örnekler iyidir, ancak örneklerin yanı sıra bir açıklama daha da iyidir.
CVn

Yanıtlar:


42

Önce yeniden adlandırmayı düşünmekte haklıydın. Sözdizimi, regex'lere alışkın değilseniz, ancak ne yaptığınızı öğrendikten sonra en hızlı / en kısa yoldan çok gariptir:

rename 's/\d{4}/2503/' file*

Bu sadece ilk 4 sayı ile eşleşir ve belirlediklerinizle değiştirir.

Ve bir test koşum ( -vnvasıta ayrıntılı olabilir ama yok do şey) sizin dosya adlarını kullanarak:

$ rename 's/\d{4}/2503/' file* -vn
file0901201437404.p renamed as file2503201437404.p
file0901201438761.p renamed as file2503201438761.p
file1003201410069.p renamed as file2503201410069.p
file2602201409853.p renamed as file2503201409853.p
file2602201410180.p renamed as file2503201410180.p

8
Bunun Debian ve türevlerinin Perl olarak değiştirildiğine dikkat edin (Ubuntu, Mint,…). Diğer Linux dağıtımlarında, renametamamen farklı bir dosya yeniden adlandırma aracıdır (Debian'ın sunduğu gibi rename.ul).
Gilles 'SO- kötülük olmayı'

Eğer dağıtım aracı bu tür bir araç kullanmıyorsa, @Michael Campbell cevabına bakınız. renameDebian'ın yaptığı gibi her dağıtım yerine varsayılanı düşünüyorum .
Astery

25

Bu hile yapmak gerekir:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done

Dördüncü ve 12. karakter arasındaki dizeyi "25032014" ile değiştirir.


bu for f in file*; do mv $f ${f/${f:4:4}/2503}; doneda işe yarıyor.
Avinash Raj

Bu iyi. Yalnızca sözcük değiştirme için normal bir kelime yapmak istiyorsanız, sed gibi çalışır. örn.for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
Eric,

1
@Eric - Cevabınızı alternatif olarak gönderdim çünkü daha net ve zarif olduğunu düşünüyorum. Siz de cevap olarak göndermek isterseniz - benimkini sileceğim. Teşekkürler!
Yehosef


Bana bir hata veriyor: "mv: 'FILE_NAME' dizini hedef değil"
Aubrey

10

bu gerçekten @ Eric'in yukarıdan gelen cevabı - ama zarif bir cevap bu yüzden daha fazla dikkat çekmek için doğru bir cevap olarak yeniden gönderiyorum.

for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done

1
ptrn='file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p'
path=/dir
( set -- "${path}/"${ptrn} ; for f ; do {
    echo "mv ${path}/${f} \
        ${path}/file25032014${f#2014}" 
} ; done )

Bu hile yapmalı. Not - Toplu mv komutlarını verme alışkanlığımda değilim - yazıldığı gibi bu sadece bir yankı. İşe yaramadan önce bunu çözmen gerekecek.


1

Dizin geçişi ile döngü yapmadan basit bir yerel yol :

find -type f | xargs -I {} mv {} {}.txt

Yerinde her dosyayı yeniden adlandırır.

Ve paralelleştirme ile çalışan bir örnek altında :

find -name "file*.p" | parallel 'f="{}" ; mv -- {} ${f:0:4}2503${f:8}'

Daha iyi bir çözüm hayal etmek kolay bir ilk yaklaşımdı. Çalışan bir komut istiyorsanız:
dtrckd

find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
dtrckd

0

Böyle bir şey yaptığınızı görürseniz, "rename.pl" ifadesine bakın. Bu bir perl betiği, ancak perl kodunu kolayca beslemenizi sağlar (/// ifadesi gibi) ve bu ifadeyi veya kodu temel alan bir toplu yeniden adlandırma yapar.

Burada temel bir sürüm var: http://stackoverflow.org/wiki/Rename.pl ama ağın etrafında yüzen başka sürümler de var. Yaşları, yaşları ve yaşları civarındaydı.

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.