Uzantıyı değiştirmek için birden fazla dosyayı mv ile yeniden adlandırın


27

Uzantılarını değiştirmek için dosyaları yeniden adlandırmak istiyorum

mv *.txt *.tsv

Ama bunu yaparken şunu alıyorum:

* .tsv bir dizin değil

İlk 10 google hitinin gösterisinin mvbu şekilde çalışması gerektiğini garip buluyorum .


Bu dosyaları tam olarak nasıl yeniden adlandırmak istediğinizi açıklamalısınız .
Totor

1
* * .GappedPeak uzantılı dosyalarım var ve onları * .bed olarak yeniden adlandırmak istiyorum. hepsi aynı dizinde, çok basit olmalı ama başarabilmek için döngü için tam bir ihtiyaç vardı
Sander Van der Zeeuw

Google'da bulduklarınızın MSDOS için geçerli olduğunu düşünüyorum.
tiktak

@ devev'in alternatif çözümü gerçekten çok yardımcı oldu
lucasvw

Yanıtlar:


22

Komutu verdiğinizde:

mv *.txt *.tsv

Kabuk, bash varsayalım sağlar genişletir joker eğer (dizinleri dahil) herhangi bir eşleme dosyaları vardır. Dosya listesi burada programa iletilir mv. Eşleşme bulunamazsa, genişletilmiş sürüm iletilir.

Yine: kabuk , programı değil, desenleri genişletir.


Örneklerin çoğu belki de en iyi yoldur, işte başlıyoruz:

Örnek 1:

$ ls
file1.txt file2.txt

$ mv *.txt *.tsv

Şimdi mvsatırda olan şey , kabuğun*.txt eşleşen dosyalara genişlemesidir . Değişmeyen *.tsvdosya olmadığı için.

mvKomut denir iki özel argümanlarla :

  • argc: Program dahil argüman sayısı.
  • argv: Programı ilk giriş olarak içeren bir argüman dizisi.

Yukarıdaki örnekte şöyle olur:

 argc = 4
 argv[0] = mv
 argv[1] = file1.txt
 argv[2] = file2.txt
 argv[3] = *.tsv

mvSon argüman, eğer programı onay görmek için *.tsv, bir dizindir. Olmadığından, program dosyaları birleştirmek için tasarlanmadığından devam edemez. (Genellikle tüm dosyaları tek bir dosyaya taşır.) Bir hevesle dizinler oluşturmaz.

Sonuç olarak hatayı durdurur ve hatayı rapor eder:

mv: target ‘*.tsv’ is not a directory

Örnek 2:

Şimdi bunun yerine söylerseniz:

$ mv *1.txt *.tsv

mvKomut ile yürütülür:

 argc = 3
 argv[0] = mv
 argv[1] = file1.txt
 argv[2] = *.tsv

Şimdi, tekrar mvolup *.tsvolmadığını kontrol edin . Değil gibi dosyaya file1.txttaşınır *.tsv. Yani: dosya, *.tsvyıldız işareti ve tümü ile yeniden adlandırıldı .

$ mv *1.txt *.tsv
‘file1.txt’ -> ‘*.tsv’

$ ls
file2.txt *.tsv

Örnek 3:

Onun yerine şöyle dedi:

$ mkdir *.tsv
$ mv *.txt *.tsv

mvKomut ile yürütülür:

 argc = 3
 argv[0] = mv
 argv[1] = file1.txt
 argv[1] = file2.txt
 argv[2] = *.tsv

Gibi *.tsvartık bir dizindir, varlık kadar dosyalar uçları orada taşındı.


Şimdi: some_command *.tsvniyetin joker karakterini saklamak olduğu gibi komutları kullanmak , daima bir alıntı yapmalı. Alıntı yaparak, herhangi bir eşleşme olması durumunda joker karakterlerin genişlemesini önlersiniz. Örneğin, söyle mkdir "*.tsv".

Örnek 4:

Örneğin, genişleme daha da görülebilir:

$ ls
file1.txt file2.txt

$ mkdir *.txt
mkdir: cannot create directory ‘file1.txt’: File exists
mkdir: cannot create directory ‘file2.txt’: File exists

Örnek 5:

Şimdi: mvkomut birden fazla dosya üzerinde çalışabilir ve yapabilir. Ancak ikiden fazla varsa sonuncusu bir hedef dizin olmalıdır. (İsteğe bağlı olarak, -t TARGET_DIRseçeneği, en azından GNU mv için kullanabilirsiniz.)

Yani bu tamam:

$ ls -F
b1.tsv  b2.tsv  f1.txt  f2.txt  f3.txt  foo/

$ mv *.txt *.tsv foo

İşte mvile çağrılır:

 argc = 7
 argv[0] = mv
 argv[1] = b1.tsv
 argv[2] = b2.tsv
 argv[3] = f1.txt
 argv[4] = f2.txt
 argv[5] = f3.txt
 argv[6] = foo

ve tüm dosyalar dizinde son bulur foo.


Linkleriniz gelince Bir yorum (bir yorumda) verdiniz, burada mvhiç bahsedilmedi, ama rename. Daha fazla bağlantınız varsa paylaşabilirsiniz. Bunun yanı sıra, iddia ettiğiniz man sayfaları için de ifade edilir.


30

Bunun sorunuzu yanıtlamadığını biliyorum, ancak dosyaları çalışma döngüsüne göre yeniden adlandırmanın başka bir yolunu arıyorsanız, neden kullanmıyorsunuz find? Bu komutu, büyük dizinlerdeki dosya uzantılarını yüz binlerce dosyayla değiştirmek için defalarca kullandım. Bu, POSIX uyumlu herhangi bir sistemde çalışmalıdır:

find . -name "*.gappedPeak" -exec sh -c 'mv "$1" "${1%.gappedPeak}.bed"' _ {} \;

Komuta Dağılımı:

  1. '. ' => 'ile işaretlenmiş geçerli dizinden başlayan arama yolu. '

  2. -name => set set eşleşen adı bul (bu durumda biten tüm dosyalar .gappedPeak )

  3. -exec => her maçta aşağıdaki komutu yürütün

  4. sh -c => 'exec' her eşleşme için bağımsız bir kabuk ortamı yaratır

  5. mv "$1" "${1%.gappedPeak}.bed"=> geçerli dosya adı olan mvilk değişken ( $ 1 ile gösterilir ) yeni isme. Burada bir alt dize eşleşmesi yapıyorum ve siliyorum; bu yüzden ilk önce tekrar var var, $ 1 ve dizeden %silmek için kullanın .gappedPeak. .bedSonunda az önce, kalan bir değişken, birleştirir ile, yeni oluşturmatest#.bedtest#.bed dosya adını.

  6. Alt çizgi 0 $ için bir yer tutucudur

  7. {}Her (yerine *.gappedPeakgöre bulunan) dosya findkomutu ve olur 1 $ için shkomuta.

  8. \;-execkomutun sonunu işaretler . Ayrıca ';'veya kullanabilirsiniz ";".

Örnek:

[user@before]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.gappedPeak
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.gappedPeak

[user@after]# ls -lh
total 0
-rw-r--r--. 1 root root 0 Jan 26 11:40 test1.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test2.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test3.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test4.bed
-rw-r--r--. 1 root root 0 Jan 26 11:40 test5.bed

Her bir parçanın ne yaptığını açıklayan komuttan geçebilir misiniz?
user1717828

Bunun için üzgünüm, gönderimi güncelledim. Umarım yardımcı olur.
Devnull

1
Müthiş, teşekkürler! Bir bash rehberi ve açıklamanızla her şeyi alabildim.
user1717828

Sorun değil. Yardım etmesine sevindim.
Ocak'ta

ÇALIŞIYOR bir cazibe gibi. İşte birden fazla alt dizinde file.abc-> için basitleştirilmiş bir örnek blub.xyz:find . -name "file.abc" -exec sh -c 'mv "$1" "$(dirname $1)/blub.xyz"' _ {} \;
Mahn

9

mv *.txt *.tsv çalışmıyor; mvbir seferde yalnızca bir dosyayı yeniden adlandırabilir. Açıklamaları yanlış anladınız veya yanlış.

mmvve renameaynı anda birkaç dosyayı yeniden adlandırabilir. Ancak renamefarklı olarak adlandırılan etrafında iki versiyonu var . Bununla ilgili bir sürü soru olmalı.


1
cyberciti.biz/tips/… Google'da ilk hit, mv'nin neden bu kadar garip bulduğumun iyi çalışması gerektiğini söylüyor
Sander Van der Zeeuw

3
@SanderVanderZeeuw Orada ne okuduğunu bilmiyorum. Örnekler kullanmaz rename, kullanmaz mv.
Hauke

1
üzgünüm yanlış HTML yapıştırdım. Bu bir udemy.com/blog/rename-a-file-in-linux oldu
Sander Van der Zeeuw

3
@SanderVanderZeeuw Utanç verici. Bu insanlar kurslar sunuyor mu? Ne yazık ki orada bir temas olasılığı görmüyorum. Bunun çalışıp çalışmadığını kolayca kontrol edebilirsiniz. Ancak mv *.txt *.tsv mviçeride (genellikle) kabuk genişletilmiş dosya adlarını görmez *.txtveya görür *.tsv. Bu joker karakterlerin genişlettiği dosya sayısı "rasgele" olur. Bunun çalıştığı tek durum, isminin *.txtdeğişmesi gereken bir dosya varsa (kelimenin tam anlamıyla) *.tsv( bashseçenek belirtilmeden nullglobayarlanmamalıdır).
Hauke,

1
Ya da daha kötüsü. Biri varsa bir dosya adında örneğin foo.txtve bir adlandırılmış varolan üzerine yazar dosyayı ...baz.tsvmv *.txt *.tsv.tsv
Runium

4

Örneğin , komutu çalıştırdığınızda dizinde bulunan dosyalar varsa asd.txtve bu iki dosyayı adlandırılmış bir dizine taşımaya çalışır . Böyle bir dizin olmadığı için hata veriyor.qwe.txtmv *.txt *.tsv*.tsv


Teşekkürler, bu kısmen açıklığa kavuşturuyor. Yine de, mv'nin birden fazla üzerinde çalışması gerektiğini iddia ettikleri çok sayıda manuel sayfa görmem çok garip buluyorum.
Sander Van der Zeeuw

2

rename(1)

renameperl yapımcısı Larry Wall tarafından yazılmış bir perl yazısı. Bir Perl regex alır ve dosya adı üzerinde çalışır.

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

Kurulum

Debian / Ubuntu

Yüklemek gerekirse renameDebian / Ubuntu üzerinde yapabileceğiniz

sudo apt install rename

0

Dikkate alınması gereken başka bir seçenek de kullanıyor:

cp -p *.txt *.tsv
rm -f *.txt
  • İlk satır, tüm *.txtdosyaları kopyalayarak *.tsvözniteliklerini koruyarak kopyalar .-p bayrak .
  • İkinci satır, tüm dosyaları desenle kaldırır *.txt
  • Bu yöntem, hem kaynak hem de hedef dosyaları geçici olarak tutmak için yeterli disk alanına sahip olmanızı gerektirir.
  • Bu yöntem, mv/ dizin / dosya adını değiştirenlerden daha yavaştır ve dosyaları farklı bir bölümde olmadıkça değiştirmeden değiştirir.
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.