Benennen Sie Unterverzeichnisse, die einem regulären Ausdruck entsprechen, rekursiv um

10

Ich habe einen Medienserver mit einem Ordner namens Series. ( /media/Expansion2/Series/)

Darin habe ich (Überraschung!) TV-Serien. Dies sind nur die Shownamen, z./media/Expansion2/Series/The Big Bang Theory/

In jedem Showordner (und hier liegt das Problem) habe ich Saisonordner. Ich habe derzeit eine Mischung aus den folgenden 2 Konventionen (zusammen mit einigen weiteren wahrscheinlich):

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

Am Ende möchte ich alle Ordner in just umbenennen Season #.

Als Regex würde ich wahrscheinlich so etwas sagen s/.*(Season \d)/$1

Gilt nur für Ordner, nicht für Dateien. Ich sollte wahrscheinlich auch erwähnen, dass dies für mehr als 50 Show-Unterordner ist, also muss es auf der /media/Expansion2/Series/Ebene beginnen und in jede Serie schauen :)

Denham Coote
quelle

Antworten:

11

Zu Debian und Derivaten (einschließlich Ubuntu):

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

Der renameBefehl ist Teil des Perl-Pakets. Es wird nicht von anderen Distributionen bereitgestellt, sondern bietet stattdessen den Standard-Linux- renameBefehl, der hier nicht hilfreich ist.

Wenn rename -n(-nicht wirklich) anzeigt, was es tun möchte, und es für Sie in Ordnung ist, lassen Sie das -n weg und machen Sie es möglich.

Benutzer unbekannt
quelle
Ich muss sagen, dass ich diese Methode in den letzten Tagen besonders nützlich fand - nicht nur für Ordner, sondern auch für Dateien. Vielen Dank.
Denham Coote
Soweit ich mich erinnere, ist das Tool mit dem Namen renameauf Debian nur . Unter Ubuntu (und einigen Varianten) wird renamees manchmal (aber nicht immer) unter gefunden , um Namenskonflikte mit dem zuvor erwähnten Standardbefehl zu vermeiden prename. Hier auf Lubuntu wird das Tool selbst aufgerufen, prenameaber es kann renameaufgrund der Symlink-Kette aufgerufen werden /usr/bin/rename -> /etc/alternatives/rename -> /usr/bin/file-rename, bei der file-renamees sich um eine leicht modifizierte Version von handelt prename.
Syntaxfehler
genial! Das hat mich dazu gebracht, das für mehrere Dateien in mehreren Verzeichnissen zu tun!
Eusoubrasileiro
2

Das folgende Snippet entfernt alles, was vor dem letzten Auftreten Season [0-9]in jedem Show-Verzeichnis unter auftritt /media/Expansion2/Series. Keine regulären Ausdrücke erforderlich, nur 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
jw013
quelle
2

Wenn Sie lieber auf Nummer sicher gehen und nur umbenennen some show/some show stuffin some show/stuff:

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

Wenn Sie vorher alles abstreifen möchten Season:

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

${var#PATTERN}entfernt PATTERN am Anfang von $varund gibt das Ergebnis zurück. ${var%PATTERN}macht das gleiche am Ende. ${var#PATTERN}und ${var%PATTERN}entfernen Sie das kürzeste übereinstimmende Präfix bzw. Suffix; ${var##PATTERN}und ${var%%PATTERN}entfernen Sie die längste Übereinstimmung.

Gilles 'SO - hör auf böse zu sein'
quelle
0

Ich werde zwei weitere Lösungen veröffentlichen, in der Hoffnung, dass sie in Zukunft hilfreich sein können. Diese kamen von den Linux-Administratoren bei der Arbeit. Nur um zu zeigen, wie viele Hämmer an diesem Nagel arbeiten werden!

Lösung 1:

Hallo Denham,

Ich muss hier einige Annahmen treffen, zum Beispiel, dass der Teil des Verzeichnisses mit "XXX Season #" immer das "externe" Verzeichnis (Blattknoten) sein wird.

Auf jeden Fall würde ich ein kleines Skript schreiben. So etwas sollte funktionieren (beachten Sie die doppelten Anführungszeichen um die Variablen, um sicherzustellen, dass Sie alle Leerzeichen in den Verzeichnissen erfassen):

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

Bevor Sie es mit dem Befehl "mv" $ {olddir} "" $ {newdir} "" ausführen, sollten Sie natürlich etwas wie "echo" $ {olddir} "" $ {newdir} "" einfügen, um sicherzustellen, dass Sie es sind Erhalten Sie die Ergebnisse, die Sie erwarten, oder Sie könnten andere Kopfschmerzen bekommen :-P


Lösung 2:

Hallo Denham,

Die meiste Antwort war bereits in der Frage. Auf jeden Fall sollte das Ausführen von Folgendem aus dem Serienordner einwandfrei funktionieren:

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  


Erläuterung:
• find -mindepth 2 -maxdepth 2 -type d (Listenverzeichnisse zwei Ebenen tiefer)
• while read dir; (Schleife in jedem Verzeichnis)
• mv -T "$ dir" (Verschieben Sie das Quellverzeichnis nach ... -T wird benötigt, um einen Fehler zu erhalten, wenn die Saisonordner nicht eindeutig sind, dh Sie haben nicht "The Big Bang Theory Season" 22 "und" Staffel 22 "im selben Verzeichnis)
• dirname" $ ​​dir "gibt den Pfad zurück, in dem sich
das Verzeichnis befindet. • Basisname" $ ​​dir "gibt den Namen des Verzeichnisses zurück.
• sed" s /. Season ([0-9] ) $ / Season \ 1 / i "vervollständigt die Magie mit regulärem Groß- und Kleinschreibung, nur für alle Fälle.

In meinem kleinen Test hat es funktioniert (versuchen Sie es zuerst mit einem Echo vor mv):

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

Denham Coote
quelle