Bir komut grubunu bir komutla yeniden adlandırma


38

.Htm uzantılı bir dosya grubum varsa, hepsini .html olarak nasıl yeniden adlandırabilirim?

mv *.htm *.html

çalışmıyor.


Sadece bütünlük uğruna, ren *.htm *.htmlWindows'ta çalışacak.
Brian Burns,

Yanıtlar:


50

Veya, saf bash kullanabilirsiniz ... (mv hariç, bu ..)

for file in *.htm; do mv "$file" "${file%.htm}.html"; done

ve kötü basename eşyalarından kaçının. ;)

Bash'in geniş bir değişken genişletme seçeneği vardır. Burada kullanılan, '%', en küçük eşleme sonekini değişken değerinden kaldırır. Desen küre şeklindedir, bu yüzden ${file%.*}de işe yarayabilirdi. '%%' operatörü en büyük eşleme sonekini kaldırır ve desen sabitlendiği için yukarıdaki örnekte değiştirilebilir ${file%%.*}.html.

Daha düzenli numaralar için bash manpage'in değişken alt bölümlerine bakın. Doğrudan bash içinde yapılabilecek çok şey var.


1
Ayrıca, bu parametre genişlemelerinin bash ile sınırlı olmadığını unutmayın . Tüm Bourne-türetilmiş mermilerde ( sh , ksh , bash , zsh , kısa çizgi , kül vb.) Bulunurlar . Genişletmeler , “Kabuk Komut Dili” için POSIX spesifikasyonunun bir parçasıdır ve oldukça taşınabilirdir.
Chris Johnsen

11

Dosya adlarında boşluk, satırsonu veya başka bir boşluk olmamalıdır, ancak freiheit'in cevabının bu versiyonu bunları ele almaktadır. Ayrıca $()diğer avantajlarla birlikte okunabilirlik için geri tepme yerine kullanır .

for file in *.htm
do
    mv "$file" "$(basename "$file" .htm).html"
done

Daha da iyisi - sadece sona ekleme özel durum için:

for file in *.htm
do
    mv "$file" "${file}l"
done

11

rename(1)tam olarak ne istediğinizi yapan bir Perl yardımcı programıdır. Bu durumda:

rename 's/\.htm$/.html/' *htm

veya alt dizinleri de kullanıyorsanız

(Bash 4.0 ve globstar ayarını gerektirir: shopt -s globstar)

rename 's/\.htm$/.html/' **/*htm


1
yeniden adlandırmak daha kolaydır, ancak standart bir unix programı değildir; Orijinal soru, hangi unix'i belirtmiyor. Bazı yerlerde "prename" gibi görünüyor.
freiheit

2
renameperl ile gelir ve temelde her unix bugünlerde perl ile gelir.
TRS-80

3
evet, fakat her unix sisteme perl koyduğunda 'rename' gibi yardımcı programlar içermez. Örneğin OSX, üzerinde "yeniden adlandırma" yapmıyor.
freiheit

1
@William: İkili yıldız işareti sözdizimi yalnızca Bash 4 ve üzeri sürümlerde ve yalnızca açıksa shopt -s globstar(varsayılan olarak kapalı) kullanılabilir. Ayrıca, Linux ve Unix'in klasörlerden çok dizinleri vardır.
Dennis Williamson

6
for file in *.htm; do
  mv $file `basename "$file" .htm`.html
done

Etrafında ilk kez bir echoönünde deneyin mv.

Orijinal belgenizdeki sorun, " mv *.htm *.html" öğesinin *kabuk tarafından işlenmesidir, bu nedenle mvkomut, geçerli dizindeki tüm .htm ve .html dosyalarının bir listesini görür. Başka bir deyişle, " mv foo.htm bar.htm stuff.htm six.htm file.htm" gibi bir şey . mv, yalnızca sonuncusu bir dizinse, ikiden fazla argümanla nasıl başa çıkılacağını bilir.


1
Boşlukları işlemek için "$ file" ifadesini kullanmalısınız.
Richard Hoskins,

Asıl sorunun tanımınız daha güçlü bir şekilde vurgulanmalıdır. Bu kabuk joker genişletme davranışı şaşırtıcıdır ve Windows ülkesinden gelen biri için sezgisel değildir ve kabuğun ne yaptığını anlamak, orijinal uygulamanın neden mvişe yaramayacağını açıkça ortaya koyar .
Greg Hewgill

3

Dize kullanarak başka bir saf bash örneği değiştirin.

for file in *.htm; do mv $file ${file/htm/html}; done

Ekstra - bu bir dizgenin tüm oluşumlarının yerini alır.

for file in *.htm; do mv $file ${file//htm/html}; done



0

Util-Linux-ng (Fedora) paketi bulunur renametarafından anlatılana benzer komutu TRS-80 . Bu şekilde kullanabilirsiniz:

rename .htm .html *.html
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.