Normal ifadeyle eşleşen alt dizinleri yinelemeli olarak yeniden adlandırma


11

Adlı bir klasör içeren bir medya sunucum var Series. ( /media/Expansion2/Series/)

İçinde, (sürpriz!) TV dizim var. Bunlar sadece şov adlarıdır, ör./media/Expansion2/Series/The Big Bang Theory/

Her şovun klasöründe (ve bu da sorunun yattığı yer) sezon klasörleri var. Şu anda aşağıdaki 2 sözleşmenin bir karışımı var (muhtemelen birkaç tane ile birlikte):

  1. /media/Expansion2/Series/The Big Bang Theory/The Big Bang Theory Season 1
  2. /media/Expansion2/Series/The Big Bang Theory/Season 2

Sonunda, tüm klasörleri sadece yeniden adlandırmak istiyorum Season #.

Bir normal ifade olarak, muhtemelen şöyle bir şey söyleyebilirim s/.*(Season \d)/$1

Yalnızca klasörler için geçerlidir, dosyalar için geçerli değildir. Muhtemelen bunun yaklaşık 50+ şov alt klasörü için olduğunu belirtmeliyim, bu yüzden /media/Expansion2/Series/seviyeden başlayıp her diziye bakması gerekiyor :)

Yanıtlar:


12

Debian ve türevleri hakkında (Ubuntu dahil):

find /media/Expansion2/Series/ -type d -exec rename -n 's/.*(Season \d)/$1/' {} ";"

renameKomut Perl paketinin bir parçasıdır. Diğer dağıtımlar tarafından sağlanmaz, bunun yerine renameburada kullanışlı olmayan standart Linux komutunu sağlarlar .

Eğer rename -n(-not gerçekten) görüntüler bunu yapmak istiyor ve sizin için tamam, -n ihmal ve gerçekleştir ne.


Söylemeliyim ki, bu yöntemi son birkaç gün içinde özellikle yararlı buldum - sadece klasörler için değil, dosyalar için de. Teşekkürler.
Denham Coote

1
Hatırladığım kadarıyla, araç sadecerename Debian'da çağrılıyor . Ubuntu'da (ve bazı tatlar), daha önce belirtilen standart komutla isim çakışmalarını önlemek için bazen (ancak her zaman değil) altında bulunur . İşte Lubuntu üzerinde, aracı kendisinin denir ama o kadar adlandırılabilir Sembolik bağ zinciri nedeniyle , biraz değiştirilmiş bir versiyonudur . renameprenameprenamerename/usr/bin/rename -> /etc/alternatives/rename -> /usr/bin/file-renamefile-renameprename
sözdizimi

müthiş! Bu beni birden çok dizindeki birden fazla dosya için yapmamı sağladı!
eusoubrasileiro

2

Aşağıdaki snippet, Season [0-9]altındaki her gösteri dizininin son gerçekleşmesinden önce gerçekleşen her şeyi kaldırır /media/Expansion2/Series. Düzenli ifade gerekmez, sadece globs.

cd /media/Expansion2/Series
for show in ./*/; do
    (
        cd "$show" || { echo "cd failed.  Skipping $show"; exit 1; }
        for season in ./*Season\ [[:digit:]]*/; do
                season_prefix=${season%Season [[:digit:]]*}
                mv "$season" ./"${season#$season_prefix}"
        done
    )
done

2

Eğer güvenli oynamak ve sadece yeniden adlandırmak isterseniz some show/some show stuffiçin some show/stuff:

for d in */; do
  for f in "$d${d%/} *"; do
    mv "$f" "${d}${f%$d${d%/} }"
  done
done

Daha önce her şeyi çıkarmak istiyorsanız Season:

for x in */*Season*; do
  mv "$x" "${x%/*}/${x##*Season}Season"
done

${var#PATTERN}başında PATTERN öğesini şeritler $varve sonucu döndürür. ${var%PATTERN}sonunda aynı şeyi yapar. ${var#PATTERN}ve ${var%PATTERN}sırasıyla en kısa eşleşen öneki ve soneki kaldırın; ${var##PATTERN}ve ${var%%PATTERN}en uzun eşleşmeyi kaldırın.


0

Gelecekte yardımcı olabilecekleri umuduyla iki çözüm daha yayınlayacağım. Bunlar işteki Linux yöneticilerinden geldi. Sadece bu çivi üzerinde kaç çekiç çalışacağını göstermeye gidiyor!

Çözüm 1:

Merhaba Denham,

Örneğin, "XXX Sezon #" ile dizinin bir parçası her zaman "dış" dizini (yaprak düğüm) olacak, burada birkaç varsayımlar yapmak zorunda.

Her durumda, küçük bir senaryo yazardım. Bunun gibi bir şey işe yaramalıdır (dizinlerdeki tüm boşlukları yakalamanızı sağlamak için değişkenlerin etrafındaki çift tırnaklara dikkat edin):

find /media/Expansion2/Series/ -type d | while read olddir
do 
   newdir=`echo "${olddir}" | awk -F "/" '$NF ~ /Season/ { last=substr($NF,index($NF, "Season")); while (i<(NF-1)) { i++; printf("/%s", $i) }; printf("/%s\n", last) } $NF !~ /Season/ { print }'`
   if [ "${olddir}" != "${newdir}" ]
   then
       mv "${olddir}" "${newdir}"
   fi
done

Tabii ki, "mv" $ {olddir} "" $ {newdir} "" komutu ile çalıştırmadan önce, "echo" $ {olddir} "" $ {newdir} "" gibi bir şey koymalısınız. beklediğiniz sonuçları almak ya da başka bir baş ağrısı ile sonuçlanabilir:


Çözüm 2:

Merhaba Denham,

Cevabın çoğu zaten soruydu. Neyse, Series klasöründen aşağıdaki gibi bir şey çalıştırmak gayet iyi çalışmalıdır:

find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "`dirname "$dir"`/`basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i"`"; done  


Açıklama:
• find -mindepth 2 -maxdepth 2 -type d (dizinleri iki düzey aşağı listele)
• dir. (her dizinde döngü)
• mv -T "$ dir" (kaynak dizinini şu konuma taşı ... -Sezon klasörleri benzersiz değilse bir hata almak için gereklidir, yani "Big Bang Theory Season'ı 22 "ve" Sezon 22 "aynı dizinde)
• dirname" $ ​​dir "dizin yolunu döndürür
• basename" $ ​​dir "dizinin adını döndürür
• sed" s /. Season ([0-9] ) $ / Season \ 1 / i "her ihtimale karşı, büyük / küçük harf duyarsız regexp ile sihri tamamlar.

Benim küçük testte çalıştı (ilk önce mv önce bir yankı ile deneyin):

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/The Big Bang Theory Season 1
./The Big Bang Theory/The Big Bang Theory Season 1/file1.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file 3.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file2.avi
./The Big Bang Theory/The Big Bang Theory Season 1/file
./The Big Bang Theory/The Big Bang Theory Season 1/3.avi
./Other Series
./Other Series/Season 2
./Other Series/Stre dsfdf sd dSeason 3

someuser@linux-box:/tmp/Series$ find -mindepth 2 -maxdepth 2 -type d | while read dir; do mv -T "$dir" "dirname "$dir"/basename "$dir" | sed "s/.*Season \([0-9]*\)$/Season \1/i""; done
mv: ./The Big Bang Theory/Season 2' and./The Big Bang Theory/Season 2' are the same file
mv: ./Other Series/Season 2' and./Other Series/Season 2' are the same file

someuser@linux-box:/tmp/Series$ find
.
./The Big Bang Theory
./The Big Bang Theory/Season 2
./The Big Bang Theory/Season 2/file1.avi
./The Big Bang Theory/Season 2/file 3.avi
./The Big Bang Theory/Season 2/file2.avi
./The Big Bang Theory/Season 2/file
./The Big Bang Theory/Season 2/3.avi
./The Big Bang Theory/Season 1
./The Big Bang Theory/Season 1/file1.avi
./The Big Bang Theory/Season 1/file 3.avi
./The Big Bang Theory/Season 1/file2.avi
./The Big Bang Theory/Season 1/file
./The Big Bang Theory/Season 1/3.avi
./Other Series
./Other Series/Season 3
./Other Series/Season 2

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.