Birden fazla dosyanın uzantısını nasıl değiştiririm?


166

Ben bir dosya uzantısını değiştirmek istiyorum *.txtiçin *.text. basenameKomutu kullanmayı denedim , ancak birden fazla dosyayı değiştirmekle ilgili sorun yaşıyorum.

İşte kodum:

files=`ls -1 *.txt`

for x in $files
do
    mv $x "`basename $files .txt`.text"
done

Bu hatayı alıyorum:

basename: too many arguments Try basename --help' for more information

Yanıtlar:


175

Düz dan Greg Wiki :

# Tümünü * .txt olarak * .text olarak yeniden adlandır
f için * .txt; yap
    mv - "$ f" "$ {f% .txt} .text"
tamam

Ayrıca neden ayrıştırmamanız gerektiğinels dair girişi görün .

Düzenleme: basenameSözdiziminizi kullanmak zorundaysanız :

f için * .txt; yap
    mv - "$ f" "$ (temel ad -" $ f ".txt) .text"
tamam

48
Burada açıklama yapılmadan kullanılan, biraz gelişmiş Bash sözdizimi var. Bunu tam olarak anlamak için Google’a bir çok şey verdim. Benim konumumdaki*.txt diğerlerine yardımcı olmak için, burada dünyalar ( sözdizimi) , çıplak çift çizgi-- ve yapı içindeki% sembolünün kullanımı${} hakkında bazı referanslar var . Şimdiye kadar son ikiyle hiç karşılaşmadım ve eskisi ile neler olup bittiğini bilmiyordum.
Mark Amery

3
Aşağıdaki Matthias Braun'un cevabına bakın - çok daha basit, aynı şeyi başarır.
btk

10
Bir linerfor f in *.txt; do mv -- "$f" "${f%.txt}.text"; done
Marçal Juan

1
Kayıpların var; Metin
Sonrası

2
@ PéturIngiEgilsson ikinci satırda mı? Hayır, gerekli değil.
jasonwryan

132

Debian'daki geçerli dizindeki tüm dosya uzantılarını şu şekilde değiştiriyorum.

rename "s/oldExtension/newExtension/" *.txt

(Bu Perl renamekomutudur, bu değil util-linux. Bkz . Debian / Ubuntu'daki rename yardımcı programı neden CentOS gibi diğer dağıtımlardan farklı? )


10
Kabul edilen cevaptan çok daha basit, teşekkür ederim!
btk

8
Mac'te bunun brew install renameçalışmasını sağladım.
Monkpit

3
balık kabuğu ile rename "s/oldExtension/newExtension/" **.txttüm * .txt özyinelemeyi yeniden adlandırmak için yapabilirsiniz
Palmstrom

3
Bu başarısız olacak footxt.txt. Bunun yerine bunu kullanın: unix.stackexchange.com/questions/19654/…
wisbucky

7
Dosyalarınızda herhangi bir uzantı yoksa ve bir tane eklemek istediğinizde:rename 's/$/.txt/' *
mkataja

34

Basit bir komut, renamegelenutil-linux , sizin için yapacak, tüm dosya eşleme "txt" için "metin" "* .txt" her tekrarlarını değiştirin:

rename txt text *.txt

4
renameİlk olay değişir, bu nedenle daha iyi olun rename .txt .text(örn o adlandırır, ama bu yine de her zaman işe yaramaz foo.txtx.bar.txtiçin foo.textx.bar.txt).
Gilles,

12
Tüm sistemlerin aynı yeniden adlandırma sürümüne sahip olmadığı unutulmamalıdır; Debian ve arkadaşlarında renamekomut perl-renamegerçektir ve perl regexes kullanır. Bunun için, eşdeğer komut şu şekilde olacaktır: rename 's/.txt/.text/' *.txt. İnsanlar, man renamehangisine sahip olduklarını bulmak için sistemlerini kontrol etmelidir .
evilsoup

@ evilsoup OSX için durum bu, thx
Davi Lima

Bu, Cygwin (Windows)
andy

27
rename "s/oldExtension/newExtension/" *.txt

Yukarıda iyi çalışıyor, ancak geçerli dizinle sınırlı. Alt dizinlerde esnek olan aşağıdaki komutu deneyin. .txtDizin yapısı altındaki tüm dosyaları yeni bir uzantıyla yeniden adlandırır .

find . -name "*.txt" -exec rename 's/.txt$/.newext/' {} \;

2
renameargüman olarak birden fazla dosyayı işleyebilir, bu kadar çok dosya varsa kullanmak +yerine çok fazla hızlandırabilirsiniz\;
Anthon

Yine de, "* .txt", kabuk tarafından desteklenmeyen büyük bir argüman listesine girebildiğinden yararlı bir seçenektir.
Roman Shapovalov

1
"s / oldExtension / newExtension /" için başarısız olur footxt.txt. Bunun yerine bunu kullanın: unix.stackexchange.com/questions/19654/…
wisbucky


9

Buradaki referanslara verilen cevaplar s/oldExtension/newExtension/yanlıştır. Eğer kullanırsanız s/txt/text/, dönüştürmek istiyorum footxt.txtiçin footext.txtistemediğiniz budur. Eğer kullansanız bile s/.txt/.text/, o dönüştürmek istiyorum footxt.txtiçin fo.text.txt.

\.Dönemi eşleştirmek için kullanmanız gerekir ( .herhangi bir karakterle eşleşir). Ve $çizginin sonuna uyacak iz . Sadece bu uzantı ile uygun şekilde eşleşir.

rename 's/\.txt$/.text/' *.txt

rename 's/\.old$/.new/' *.old

7

@Prince John Wesley cevap dayanarak, buradan geçerli dizindeki tüm dosyaları uzantıları değiştirmek için basit bir bash script ext1için ext2. Ayrıca yeniden adlandırılan dosyaların adlarını da verir.

#!/bin/bash
for f in *.$1
do
    [ -f "$f" ] && mv -v "$f" "${f%$1}$2"
done

Örnek kullanım (betiğin adını varsayarsak change-ext):

change-ext ext1 ext2

Dizinlerdeki dosyaların uzantılarını art arda değiştirmek için, ikinci satırı ( for...) iki satırla değiştirin: shopt -s globstarve for f in **/*.$1. Bash 4+ gerektirir.
Dennis Golomazov


3

Diyelim ki dosyalarınız çeşitli dizine dağılmış, diyelim ki bu sizin ana dizininizdir

for f in `find /dirx -iname '*.txt' -type f -print`;do  mv "$f" ${f%.txt}.text; done

Ya tcsh ..
Josef Klimuk

2

İşte benim işime yarayan bu:

find . -name '*.txt' -exec rename 's/\.txt$/.text/' \{} \;

1
LÜTFEN ekleyin "metin" den önce
danielmhanover

2

Sen ne zaman

kaynak dosyalar için bir uzantı yok

ve hedef uzatma .text'tir , bu şekilde yaparsınız -

for f in *; do mv -- "$f" "${f%.\*}.text"; done

1
Mükemmel bash-native betiği. harika çalıştı! for f in *.html; do mv -- "$f" "${f%.\*}.pug"; done
TamusJRoyce

1

Sürümünüzde nelerin yanlış gittiğini bilmek istiyorsanız: Basename komutunda $filesbunun yerine kullanılır $x. Öyleyse bu çalışmalı (denenmemiş olsa da):

for x in *.txt
do
  mv "$x" "`basename '$x' .txt`.text"
done
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.