Bir dizindeki birden çok dosyayı aynı anda yeniden adlandırma


12

/var/tmp/abc4 Dosyadan oluşan dizin var :

12345-ram-3e3r5-io9490-89adu9.csv
45434-dam-qwe35-to9490-43adu9.csv
11234-cam-yy3r5-ro9490-85adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv

Tüm CSV dosyalarını (tüm dosyaları bulmak ve onları yeniden adlandırmak) mümkün olan en kısa (muhtemelen bir satır) şekilde yeniden adlandırmak istiyorum:

XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

Yanıtlar:


15

rename -n 's/(\w+)/XXXXX/' *.csv

-nmutlu olduğunda çıkarın .


2
İçin uygun bir versiyonu rename. Bu Larry Duvar adlı olduğunu varsayalım renamegelen rename(ve IIRC Debian ve türevi de paketin prenameRedHat ikna sistemlerde). Çok kullanışlı bir araç.
xenoid

2
perl-renamekemer linux
lesmana

1
@SHawarden, değiştirme desenini anlamak için komutu yürütmeye ve man sayfasının ilgili bölümünü okumayı denedim, ancak verbosebayrağı eklerken hiçbir şey çıktısı yok ve mevcut yolun olmasına rağmen dosya adı değişikliklerini gerçekleştirmiyor benzer adlara sahip dosyalar 12345_foo.csv. Çalıştırmak için herhangi bir ek görev yapmam gerekiyor mu (şu anda Fedora 30'da)? Döngüden daha temiz bir yaklaşımdır. Şimdiden teşekkürler!
danieldeveloper001

3
@ danieldeveloper001 kullandınız mı renameveya prename? Yukarıdaki yorumuma bakın. man {the command}sonunda yazarları listeler.
xenoid

2
Bu yalnızca Debian kaynaklı sistemlerde çalışır. Fedora'dan türetilen sistemler tamamen farklı bir renamekomuta sahiptir; bkz. unix.stackexchange.com/a/238862/135943
Wildcard

11

Deneyin:

for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done

Nasıl çalışır:

  • for f in *.csv; do

    Bu, tüm *.csvdosyalar üzerinde bir döngü başlatır .

  • mv -i -- "$f" "XXXXX-${f#*-}"

    Bu, dosyaları istediğiniz gibi yeniden adlandırır ve herhangi bir dosyanın üzerine yazmadan önce etkileşimli olarak sorar.

  • done

    Bu, döngünün sonunu gösterir.

Misal:

$ ls -1
11234-cam-yy3r5-ro9490-85adu9.csv
12345-ram-3e3r5-io9490-89adu9.csv
14423-sam-hh3r5-uo9490-869du9.csv
45434-dam-qwe35-to9490-43adu9.csv
$ for f in *.csv; do mv -i -- "$f" "XXXXX-${f#*-}"; done
$ ls -1
XXXXX-cam-yy3r5-ro9490-85adu9.csv
XXXXX-dam-qwe35-to9490-43adu9.csv
XXXXX-ram-3e3r5-io9490-89adu9.csv
XXXXX-sam-hh3r5-uo9490-869du9.csv

4

Gönderdiğiniz küçük zorluğu sevdim, işte benim çözümüm. Tüm dosyalarınızın 5 sayısal karakterle başladığını varsayıyorum, bu nedenle ilk sayısal dosyaları "XXXXX" ile değiştirmek için cut komutunu kullanın.

Aşağıda, komuttan önceki dosyalar.

-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 11111_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 12345_baz_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml

Aşağıda, bir astar komutu.

for src in *.csv; do dst=XXXXX$(echo $src| cut -c6-); mv $src $dst; done;

Aşağıda, komuttan sonraki dosyalar.

-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 67890_foo_file.xml
-rw-rw-r--. 1 daniel daniel 0 May 13 22:54 XXXXX_bar_file.csv
-rw-rw-r--. 1 daniel daniel 0 May 13 23:18 XXXXX_baz_file.csv

Aradığın şey bu mu? :)

Referanslar:

Bash komut çıkışıyla döngü

Bash dizeleri


2
Bash, bu tür dize manipülasyonunu yapabilir, her biri için yeni bir işlem yapmaya gerek yok, lütfen diğer cevabı nasıl yapacağınız.
chx

1
@chx, diğer cevapları zaten gördü ve ondan biraz bilgi aldı, ancak onları işaret ettiğiniz için teşekkürler. Lütfen biraz açıklar no need to fork a new process for eachmısınız?
danieldeveloper001

3
cutayrı bir ikili dosyadır ( /usr/bin/cut) ve çalıştırmak kabuk yerleşik ins kullanmaktan daha fazla kaynak tüketir.
chx

2
Görüyorum ki, aslında amaç çok sayıda dosyayı yeniden adlandırmak önemli. Açıklama için teşekkürler!
danieldeveloper001

1

çatal yok:

ls | perl -lne '$suf=substr($_,6); rename $_, "XXXXX-$suf"'

Bir kabuk döngüsü kullandığınızda, mvçatallar dosya başına bir kez. Perl'in renameemri yoktur.

(Perl'in yeniden adlandırma komutunun bazı kısıtlamaları vardır, ancak bu özel durumda bu kısıtlamalar geçerli değildir.)

Daha renameönce gösterilen komuta gelince , evet işe yarıyor, ama sonra iki farklı yeniden adlandırma türü ve benzeri arasındaki tüm karışıklığa sahipsiniz. Doğru olana sahipseniz, harika, ama değilse, bu da işe yarar.

Perl-rename komutuna sahip değilseniz ve yükleyemiyorsanız, bunu yapabilirsiniz:

ls | perl -lne '$old=$_; s/(\w+)/XXXXX/; rename $old, $_'

Gördüğünüz gibi, bu üst yanıtta gösterilen aynı ikameyi kullanır. Elbette perl-rename'in diğer çanları ve ıslıkları var (yukarıda bahsedilen en büyük cevap -nzaten var, o zaman var -0, -fvb.) Ve ne kadar çok ihtiyacınız olursa, bu şekilde kendi yerine yuvarlamak yerine bunu daha fazla yüklemelisiniz .


Bir borunun olağan uygulamalarında çatallar olacaktır.
muru

Ben "mv" çatal / usr / bin / mv ya da her neyse, kabuk bile aksine, "yeniden adlandırılacak dosya başına bir kez çatal olmaz" demek istedim. Bunun nedeni, "rename" komutunun doğrudan libc'de rename () yöntemini çağıran bir perl iç komut olmasıdır. Elbette bazı kısıtlamaları vardır, ancak bu özel örnekte bu kısıtlamalar geçerli değildir.
sitaram

1
Bu renamekomut için de geçerlidir ( üst yanıt , Perl de kullanır), bu yüzden belki de cevaba sadece "çatal yok" dan biraz daha fazla açıklama eklemelisiniz.
muru
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.