Uzun isim ile Linux mv dosyası


19

Linux'ta bazen böyle dosyaları yeniden adlandırıyorum:

mv dir1/dir2/dir3/file.txt  dir1/dir2/dir3/file.txt.old

Ben sadece dosyayı yeniden adlandırmak istiyorum, başka bir dizine taşımak istiyorum unutmayın.

Bu komutun stenografi versiyonunu yapmama izin verecek bir komut var mı? Şöyle bir şey düşünüyorum:

mv dir1/dir2/dir3/file.txt  file.txt.old

veya belki de (sadece isme eklemek için) gibi bir şey:

mv dir1/dir2/dir3/file.txt  {}.old

Amacım tam yolu tekrar belirtmek zorunda değil.

Yazdığım bu "örnekler" in işe yaramadığını biliyorum, ama bu sadece neyi başarmak istediğime dair bir fikir.

Dizine cd girmek istemiyorum.


8
Neden dizine geçmiyorsun? Hızlıdır ve sorununuzu çözer.
Michael Hampton

Ben aynı yerden birçok alt dizinleri ile uğraşıyorum, ben her zaman bu üst dir geri geliyor olması gerekiyorsa daha yavaş
santiago arizti

3
Kimse başka bir dizine geçmen gerektiğini söylemedi, sadece istediğin dizine.
Michael Hampton

Harici komut çağırma sırasında kaçınılması (cd dir1/dir2/dir3 && exec mv file.txt{,.old})nedeniyle, her iki şekilde de tam olarak bir çatala sahip olduğunuz için alt işlem olmadan kodla aynı performansa sahip olduğunu unutmayın . execfork()
Charles Duffy

Yanıtlar:


45

tek bir dosya için dene

mv dir1/dir2/dir3/file.{txt,txt.old}

nerede X{a,b}yapı genişletmekXa Xb kullanarak bir önizleme yapabilirsiniz

echo dir1/dir2/dir3/file.{txt,txt.old}

İhtiyacınıza uygun olup olmadığını görmek için.

Not:

  1. birden fazla dosya için

    mv dir1/dir2/dir3/file{1,2,3}.{txt,txt.old}
    

istediğiniz şeye genişleme olasılığı düşüktür. (bu, karışık bir file.txt file1.txt.old file2.txt ... dosyasına genişleyecektir.)

  1. {txt,txt.old} kısaltılabilir {,.old}yorum başına

  2. dizin adı açık değilse, joker karakter kullanılabilir.

    mv *1/*2/d*/*.{,old}
    

çoklu dosya kullanımı için rename

rename -n s/txt/old.txt/ dir1/dir2/dir3/file*.txt 

-nyeniden adlandırmak için bırakın .


1
güzel, bu genişleme yolunu bilmiyordum! teşekkür ederim
santiago arizti

14
Misiniz mv dir1/dir2/dir3/file.txt{,.old}da çalışabilir ve hatta daha kısa olamaz?
Josh

3
@Josh Evet, mükemmel çalışıyor ve daha az tuş vuruşu gerektiriyor. Bu yapıyı çok düzenli kullanıyorum.
rlf

2
yıllardır Linux kabuğunu nasıl kullanabileceğiniz ve her zaman yeni numaralar bulabileceğiniz komik
Santiago arizti

Sanırım bash dilinde resmi bir eğitim almış olsaydım, tüm bu "hileler" daha açık olurdu, ama sadece geçinmek için yeterince öğreniyordum.
santiago arizti

6

Komut, renameeşleşen tüm dosyaları yeniden adlandırır. Ana amacı birden fazla dosyayı yeniden adlandırmaktır, ancak Perl ifadesi yalnızca bir dosyayla eşleşiyorsa, yalnızca bu tek dosyayı yeniden adlandırır. Detaylar ve dagitim temelli sözdizimi için manpage okuyun: man rename.

Örnek kullanım: "/path/file.txt" dosyasını "/path/file.txt.old" olarak yeniden adlandırın:

rename 's/file.txt/file.txt.old/g' /path/file.txt

Daha kısa gösterim (shalomb sayesinde):

rename 's/$/.old/' /path/file.txt
rename '$_.=".old"' /path/file.txt

Kuru çalışma için rename -n.

Daha fazla örnek ve ayrıntıyı https://thepcspy.com/read/bulk-rename-files-in-ubuntu/ adresinde bulabilirsiniz.


Güzel, yeniden adlandırma komutunu biliyordum, yapabileceği her şeyi asla bilmiyordum, teşekkürler!
santiago arizti

6
Ne yazık ki farklı Linux dağıtımlarının renametamamen farklı davranışlarla farklı komutları vardır.
18'de kasperd

1
.oldDosya adına ekleyerek bu yeniden adlandırma görevi için, muhtemelen bir rename 's/$/.old/' /path/to/file.txtveya yapmak biraz daha uygunrename '$_.=".old"' /path/to/file.txt
shalomb

@Fabian - Ben nitpicking değildi, sadece OP arıyor sık ​​kullanılan bir deyim gibi görünüyor için "en kısa el" hedefleyen :)
shalomb

4

Bir kerelik durum için, geçerli dizinimi değiştirmek istemezsem, sadece bir alt kabuk kullanabilirim:

(cd dir1/dir2/dir3/ && mv file.txt file.txt.old)

Eğer Çünkü cdalt kabuğun içinde, size gerçek kabuğunda senin dizini değişmemiştir


4
Daha hızlı ve daha güvenli kullanım && exec mv- bu şekilde cdbaşarısız olursa yeniden adlandırma yapmaya çalışmazsınız ve execalt kabuğu tüketir, böylece performans cezasından kaçınırsınız.
Charles Duffy

Katılıyorum && Dediğim gibi, ben alt kabuğun maliyeti hakkında değil endişe (basit tutmak: edememek kolaylıkla IMO daha önemlidir nasıl hatırlamak) olur, bir seferlik durum için
Adam

Sana etkili yolu hatırlayarak, sadece tek yönde hatırlamak gidiyoruz emin bunu durumlarda verimsiz rotayı gitmez yapmak yardımcı olduğunu iddia ediyorum yapar olsun.
Charles Duffy

4

@ Archemar'ın {} genişletme kullanma çözümünü seviyorum, çünkü komut satırınızı zaten başlattığınızda kullanabilirsiniz. İşte tamlık için başka olasılıklar:

F="dir1/dir2/dir3/file.txt" ; mv "$F" "$F.old"

(tırnak işaretleri yalnızca adında boşluk veya başka sözcük kesme karakterleriniz varsa gereklidir)

mymv() {
    mv "$1/$2" "$1/$3"
}

mymv dir1/dir2/dir3 file.txt file.txt.old
mymv dir5/dir6/dir7 file.txt file.txt.old

Notlar:

  • Bu bash sözdizimi, başka bir kabuk kullanıyor olabilirsiniz
  • mymv herhangi bir makul dize olabilir, "benim hareket" için mymv kullanılır.
  • İşlev tanımı .bash_profile dosyasına eklenebilir

Bir diğeri:

cd dir1/dir2/dir3 ; mv file.txt file.txt.old ; cd -

fakat

(cd dir1/dir2/dir3/ && exec mv file.txt file.txt.old)

(@Adam ve @CharlesDuffy'dan) cd'nin arızalanması durumunda tartışmasız daha iyidir.


1
Kullanmayın mmv, zaten bu şekilde adlandırılmış bir program var.
glglgl

1
@glglgl Bitti :)
Law29

2

mvKomutu kısaltmak için alt dizini girmek , ancak daha sonra geçerli dizine geri dönmek istiyorsanız, bunu yapmanın iki yolu vardır. Biri koymak cdvemv alt kabuğuna (daha önce önerildiği gibi).

Diğeri dizinleri kullanmak pushdve popddeğiştirmek:

pushd dir1/dir2/dir3/; mv file.txt file.txt.old; popd

pushdKomut gibidir cdöncelikle bir yığını üzerine Geçerli dizinin adını iter hariç. popden üstteki adı yığından kaldırır ve bu dizinde değişiklik yapar.


pushdve popdetkileşimli kullanım için tasarlanmış uzantılardır - POSIX bunları açıkça "sonuçlar belirtilmemiş" olarak listeler ve komut dosyalarını çalıştırmak için oluşturulmuş bir kabuğun (yani, en az yerleşik bir ortamda) bunları desteklemesi gerekmez.
Charles Duffy

2

Sadece yaparım

cd dir1/dir2/dir3/
mv file.txt file.txt.old
cd ~- # go to the most recent directory

0

Aşağıdakileri içeren çözüm: mv something{.txt,.txt.old}"bashizm" kullanıyor. Daha değişken bir yol istiyorsanız, ortak değişken manipülasyonları kullanarak:

# rename all files "file*.txt" of directory /dir1/dir2/dir3 into file*.txt.old:
for f in dir1/dir2/dir3/file*.txt ; do
  mv "$f" "${f/.txt/.txt.old}"  # note there are no terminating "/"
done


# "${var/A/B}" is the content of var with the first occurence of "A" replaced by "B"

2
İlgili POSIX spesifikasyonu için pubs.opengroup.org/onlinepubs/009695399/utilities/… adresine bakın - ${var/text/replacement}bir bashizmdir.
Charles Duffy

@CharlesDuffy oh ... Beni üzdün :(
Olivier Dulac
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.