Yanıtlar:
renameUbuntu ile birlikte gelen araç bu tür şeylerde oldukça sıcak. Bunun gibi küçük Perl ifadelerini gömebilirsiniz:
rename -n 's/.+/our $i; sprintf("AS%d.txt", 1+$i++)/e' *
Bu sadece ne yapacağını gösterecektir. -nBunu canlı yangın egzersizi yapmak için kaldırın .
Bu temelde bir değişkeni kabaca tanımlayarak ve vurduğumuz her dosyayı arttırarak çalışır. 10'dan fazla dosyaya sahip olacaksanız sprintf,. Aşağıdakiler iyidir 999:
rename -n 's/.+/our $i; sprintf("AS%03d.txt", 1+$i++)/e' *
... Ama bu genişleyecek kadar kolay.
Oli adlı @ geliştirmek için cevap , renamealet versiyonu 1.600 tarafından Aristo Pagaltzis aslında yerleşik bir sayaç $N.
Tek ihtiyacınız olan şey,
rename 's/AS.*/AS$N/' *
Yüklemek,
brew install renameveya komut dosyasını indirin/usr/local/bin/brewveya /usr/bin)renamedoğrudan atamanızı sağlar $_, bu da bu sorun için idealdir.Biz Perl geçmek kod argümanları rağmen renamefayda sıklıkla eşleştirme ve ikame (gerçekleştirebileceğiniz s/), ve öyle tamamen kabul etmek bu sorunu bu şekilde çözmek , bu aslında inceleyerek değiliz birine veya benzeri durumlarda buna hiç gerek orada gerçekten eski dosya adlarının yeniden kullanılması. renamehemen hemen her Perl kodunu yazmanıza izin verir ve içine gömülmesine gerek yoktur s/ /e. Ben böyle bir komut kullanmanızı öneririz:
rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' *
Ya da birkaç karakteri tıraş etmek istiyorsanız:
rename -n '$_ = sprintf "AS%02d.txt", ++our$i' *
(Daha da kısaltılabilir, ancak netlikten ödün vermeden yapılamaz.)
Her iki komut da aynı şeyi yapıyor. Her biri hangi yeniden adlandırma işlemlerinin gerçekleştirileceğini gösterir. Birini denedikten ve sonuçlardan memnun kaldığınızda, -nseçenek olmadan tekrar çalıştırın . Yazılı gibi, bu dosya adları üretecektir AS01.txt, AS02.txt, ..., AS10.txt, AS11.txt, vb. Bunları gerektiği gibi değiştirebilir, ardından yalnızca -ngördüklerinizi istediğiniz zaman kaldırabilirsiniz .
2'den daha büyük bir genişliğe ped yapmak istiyorsanız, yerine 2daha büyük bir sayı koyun. Herhangi bir nedenle dosya adları gibi isterse Örneğin, AS00000000000001.txt, sen yerini alacak %02dolan %014d. Eğer hiç dolgu istemiyorsanız - dosyalarınızı daha sonra listelediğinizde sayısal olmayan bir sırada görünmesine rağmen - o zaman %02dsadece değiştirebilirsiniz %d.
Bu nasıl çalışıyor? Kabuğunuz komutu *çalıştırmadan önce bir dosya listesine genişlerrename . Liste, geçerli yerel ayarlarınıza göre sözlükbilimsel olarak (yani alfabetik olarak) sıralanır. renamedosya adlarını komut satırı bağımsız değişkenleri olarak alır ve listelendikleri sırayla işler. İfade ++$i, değişkenin geçerli değerinden bir daha büyük olarak değerlendirilir $ive ayrıca değişkeni $iyeni artan değere ayarlar . Bu değer, sprintfonu biçimlendiren ve diğer metnin içine yerleştiren iletilir . Bu metin doğrudan $_dosya adını tutan özel değişkene atanır . Bu yana renamebu bağımsız değişken olarak geçirilir amacıyla işlemler dosyaları, buna göre numaralandırılır.
Hem bir sayaç değişkeni sprintfbildirir hem de artırır ve her ikisi de , esasen sıfırlarla doldurulmuş bu sayacın değerini yeni dosya adlarının diğer metnine gömmek için aynı şekilde kullanılır. (Sıfırlarla doldurma ve doldurma genişliğini değiştirme hakkında her iki yanıt için de her ikisi için de eşit şekilde geçerli olan bilgiler.) Bu kadar benzer olmasının nedeni, daha eski yanıttaki yöntemin gerçekten sadece 1 yapmasıdır , ancak birçok sorun için yararlı olan ancak bunun için aslında gerekli olmayan ekstra adımlarla.
Karşılaştırma için, burada kullandığım stili kullanacak şekilde değiştirilmişse (ve burada yaptığım gibi 3 yerine 2 genişliğine geçmek için) bu cevabın ikinci komutu şöyle görünür:
rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' *
Bu komut arasındaki s/.+/ve /ebu komutun içindeki kısım , şimdi bu yanıttaki ilk komutta atadığım $_ifadeyle (yani =operatörün sağ tarafındaki kod ) aynı.
s/ Operatör maç metne girişimleri (dosya adları kabuk genişletilmiş olduğunu *ve onu ran komut satırı argümanları olarak geçirilen rename) bir ile normal ifade ve gerçekleştirdiği ikamesi. ifadesi /, sifadenin farklı bölümlerini ayırmak için bir sınırlayıcı olarak kullanılmaktadır . İlk bölüm, .+düzenli ifadedir; herhangi bir 1 karakterle ( .) eşleşir ve bunu bir veya daha fazla kez ( +) yapar . Dosya adları asla boş olmadığından - her zaman en az bir karakter uzunluğundadır - bu, 1 dosya adıyla eşleşmenin bir yoludur .our $i; sprintf "AS%02d.txt", ++$i. Bu yeni dosya adını üretir. Tipik olarak, (a) dosya adının sadece bir kısmıyla eşleşen metni değiştirmek veya (b) eşleşen metne bir şekilde dayalı olarak s/metin üretmek için kullanılır (örneğin, aşağıdakilere genişleyen özel bir değişken kullanabilir) maç). Bu durumda, eşleşen metin hiç kullanılmıyor.$&our $i; sprintf "AS%02d.txt", ++$ibir dosya ismi gibi kullanılacak olan, olmayan kod olarak çalışır. Ancak /esondaki bayrak, metnin Perl kaynak kodu olarak değerlendirilmesine ve değerlendirilmesine neden olur ve bunu yaparak üretilen değeri (bu durumda Perl'in yerleşik sprintfişlevinin dönüş değeri ) yeni dosya adı olarak kullanır.Ben burada gösterdiğim yöntem daha net ve daha basit bir yaklaşım olduğunu düşünüyorum rağmen bu sorunun kullanımları olduğu herhangi bir yöntemle daha s/ile /ede diğer dosya yeniden adlandırma sorunların hepsi bir takım için uygundur, çünkü 's iyi, o tekniğin farkında olmak veya orijinal dosya adlarının bir kısmı incelenir ve / veya saklanır. Bu blog örneklerini içeren Oli ( bu yanıtı da yazdı ) tarafından yazılan bu blog gönderisini öneriyorum .
1. Teknik olarak, orada olduğu davranışında fark $_ =komutları ve s/ /ekomutlar. Normal ifadede .+, herhangi bir karakterle .eşleşen kesinlikle doğru değildir , çünkü bir satırsonu ile eşleşmez . Büyük olasılıkla dosyalarında yeni satırlar içeren dosya adları kullanmamalısınız, ancak bazen bir dosya yanlışlıkla bu şekilde adlandırılır. Eğer böyle hissediyorsanız, çıktısını kontrast Bunun için . Bir satırsonu eşleşmesi yapmak için, sonuna gelen (ile ) bayrağını kullanın . Yani, yerine sonuna yaz .rename -n 'our $i; $_ = sprintf "AS%02d.txt", ++$i' $'foo\nbar'rename -n 's/.+/our $i; sprintf "AS%02d.txt", ++$i/e' $'foo\nbar'.se/se/e
Yeniden adlandırmak istediğiniz ~/Adirdosyaların bulunduğunu ve bu klasördeki tek dosyaların olduğunu varsayalım :
n=0
for f in $( ls ~/Adir | sort ) ; do
n=$(( n+1 ))
mv -n "$f" "AS${n}.txt"
done
Bu komut dosyası içindeki her dosyaya bakar ve dosya yoksa ~/Adiryeniden adlandırılır AS1.txt, AS2.txt, ...(üzerine yazma yapılmaz). Bu yüzden bunların içindeki tek dosya olduğundan emin olmalısınız ~/Adir. sortKomut dosyaların ilk düzeni sağlamak isteyen sadece durumda olduğunu.
renameadı ön addır. Bu daha iyi olabilir, ancak bu cevabı daha değerli hale getirmek için kurulum talimatları eklemek isteyebilirsiniz.