Yanıtlar:
rename
Ubuntu 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. -n
Bunu 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 , rename
alet 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 rename
veya komut dosyasını indirin/usr/local/bin/brew
veya /usr/bin
)rename
doğrudan atamanızı sağlar $_
, bu da bu sorun için idealdir.Biz Perl geçmek kod argümanları rağmen rename
fayda 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ı. rename
hemen 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, -n
seç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 -n
gördüklerinizi istediğiniz zaman kaldırabilirsiniz .
2'den daha büyük bir genişliğe ped yapmak istiyorsanız, yerine 2
daha büyük bir sayı koyun. Herhangi bir nedenle dosya adları gibi isterse Örneğin, AS00000000000001.txt
, sen yerini alacak %02d
olan %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 %02d
sadece 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. rename
dosya 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 $i
ve ayrıca değişkeni $i
yeni artan değere ayarlar . Bu değer, sprintf
onu 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 rename
bu 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 sprintf
bildirir 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 /e
bu 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 /
, s
ifadenin 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", ++$i
bir dosya ismi gibi kullanılacak olan, olmayan kod olarak çalışır. Ancak /e
sondaki 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 sprintf
iş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 /e
de 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/
/e
komutlar. 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'
.
s
e
/se
/e
Yeniden adlandırmak istediğiniz ~/Adir
dosyaları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 ~/Adir
yeniden 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
. sort
Komut dosyaların ilk düzeni sağlamak isteyen sadece durumda olduğunu.
rename
adı ön addır. Bu daha iyi olabilir, ancak bu cevabı daha değerli hale getirmek için kurulum talimatları eklemek isteyebilirsiniz.