Soms heb je een map met tientallen bestanden waarvan de bestandsnamen veel langer zijn dan nodig. Handmatig ieder bestand hernoemen kan natuurlijk, maar met Bash kun je dit in één keer doen.
Stel dat je een map met videobestanden hebt:
Mijn Video S01E01 De eerste aflevering.mkv
Mijn Video S01E02 Een nieuw begin.mkv
Mijn Video S01E03 Het vervolg.mkv
Mijn Video S01E04 De ontdekking.mkv
Je wilt alleen de naam van de serie en het afleveringnummer behouden:
Mijn-Video-S01E01.mkv
Mijn-Video-S01E02.mkv
Mijn-Video-S01E03.mkv
Mijn-Video-S01E04.mkv
Dat kunnen we met een klein Bash-script automatiseren.
Stap 1 – Ga naar de juiste directory
Open een terminal en ga naar de map waarin de bestanden staan:
cd "/pad/naar/de/videos"
Controleer eventueel eerst de inhoud:
ls -1
Stap 2 – Doe eerst een proefrun
Voordat we daadwerkelijk bestanden gaan hernoemen, is het verstandig om eerst te bekijken wat het commando van plan is.
for f in *; do
if [[ "$f" =~ (S[0-9]{2}E[0-9]{2}) ]]; then
ext="${f##*.}"
echo "$f -> Mijn-Video-${BASH_REMATCH[1]}.$ext"
fi
done
Er wordt nu nog niets gewijzigd. echo laat alleen zien wat de nieuwe bestandsnamen zouden worden.
De uitvoer ziet er bijvoorbeeld zo uit:
Mijn Video S01E01 De eerste aflevering.mkv -> Mijn-Video-S01E01.mkv
Mijn Video S01E02 Een nieuw begin.mkv -> Mijn-Video-S01E02.mkv
Mijn Video S01E03 Het vervolg.mkv -> Mijn-Video-S01E03.mkv
Mijn Video S01E04 De ontdekking.mkv -> Mijn-Video-S01E04.mkv
Controleer deze lijst goed voordat je verdergaat.
Wat gebeurt hier precies?
Het belangrijkste gedeelte is:
(S[0-9]{2}E[0-9]{2})
Dit is een reguliere expressie die zoekt naar een patroon zoals:
S01E01
S01E02
S02E15
S10E06
S staat hier voor seizoen en E voor aflevering.
Het gedeelte:
[0-9]{2}
betekent dat er precies twee cijfers worden gezocht.
Wanneer Bash bijvoorbeeld S01E03 vindt, wordt dat gevonden gedeelte beschikbaar via:
${BASH_REMATCH[1]}
Met:
ext="${f##*.}"
halen we de bestandsextensie uit de oorspronkelijke bestandsnaam.
Bij:
Mijn Video S01E03 Het vervolg.mkv
wordt ext dus:
mkv
Hierdoor blijft de oorspronkelijke bestandsextensie behouden.
Stap 3 – De bestanden echt hernoemen
Klopt alles in de proefrun? Dan kunnen we echo vervangen door mv:
for f in *; do
if [[ "$f" =~ (S[0-9]{2}E[0-9]{2}) ]]; then
ext="${f##*.}"
mv -- "$f" "Mijn-Video-${BASH_REMATCH[1]}.$ext"
fi
done
De bestanden worden nu daadwerkelijk hernoemd.
Controleer daarna het resultaat:
ls -1
Je krijgt dan bijvoorbeeld:
Mijn-Video-S01E01.mkv
Mijn-Video-S01E02.mkv
Mijn-Video-S01E03.mkv
Mijn-Video-S01E04.mkv
Variant: 2x01 in plaats van S02E01
Niet alle videobestanden gebruiken dezelfde notatie voor seizoen- en afleveringsnummers. Je kunt bijvoorbeeld bestanden tegenkomen die er zo uitzien:
Mijn Video 2x01 De eerste aflevering.mp4
Mijn Video 2x02 Een nieuw begin.mp4
Mijn Video 2x03 Het vervolg.mp4
Mijn Video 2x04 De ontdekking.mp4
Hier staat 2x01 voor seizoen 2, aflevering 1.
Het eerdere script werkt hier niet mee. Dat zoekt namelijk specifiek naar een patroon zoals S02E01. Als zo’n patroon niet in de bestandsnaam voorkomt, wordt er niets gevonden en krijg je bij de proefrun dus ook geen uitvoer.
We kunnen de reguliere expressie aanpassen om het 2x01-patroon te herkennen en tegelijkertijd om te zetten naar de S02E01-notatie.
Doe ook hier eerst een proefrun:
for f in *; do
if [[ "$f" =~ ([0-9]+)x([0-9]{2}) ]]; then
season="${BASH_REMATCH[1]}"
episode="${BASH_REMATCH[2]}"
ext="${f##*.}"
printf -v season "%02d" "$season"
echo "$f -> Mijn-Video-S${season}E${episode}.$ext"
fi
done
De uitvoer ziet er dan bijvoorbeeld zo uit:
Mijn Video 2x01 De eerste aflevering.mp4 -> Mijn-Video-S02E01.mp4
Mijn Video 2x02 Een nieuw begin.mp4 -> Mijn-Video-S02E02.mp4
Mijn Video 2x03 Het vervolg.mp4 -> Mijn-Video-S02E03.mp4
Mijn Video 2x04 De ontdekking.mp4 -> Mijn-Video-S02E04.mp4
Hoe werkt deze variant?
Dit keer zoeken we met:
([0-9]+)x([0-9]{2})
Bij bijvoorbeeld 2x03 worden twee onderdelen opgeslagen.
Het eerste gedeelte:
${BASH_REMATCH[1]}
bevat het seizoen:
2
Het tweede gedeelte:
${BASH_REMATCH[2]}
bevat het afleveringsnummer:
03
Vervolgens gebruiken we:
printf -v season "%02d" "$season"
Hiermee wordt van seizoen 2 netjes 02 gemaakt.
We kunnen vervolgens zelf de gebruikelijke notatie opbouwen:
S02E03
Klopt de proefrun? Dan kunnen de bestanden daadwerkelijk worden hernoemd:
for f in *; do
if [[ "$f" =~ ([0-9]+)x([0-9]{2}) ]]; then
season="${BASH_REMATCH[1]}"
episode="${BASH_REMATCH[2]}"
ext="${f##*.}"
printf -v season "%02d" "$season"
mv -- "$f" "Mijn-Video-S${season}E${episode}.$ext"
fi
done
Daarmee worden bijvoorbeeld:
Mijn Video 2x01 De eerste aflevering.mp4
Mijn Video 2x02 Een nieuw begin.mp4
omgezet naar:
Mijn-Video-S02E01.mp4
Mijn-Video-S02E02.mp4
Dit laat ook meteen zien waarom het belangrijk is om eerst naar de bestaande bestandsnamen te kijken. Een script dat zoekt naar S02E01 kan niet automatisch weten dat 2x01 hetzelfde betekent.
Het patroon in het script moet dus overeenkomen met het patroon in je bestandsnamen.
Waarom staat er -- achter mv?
In het commando gebruiken we:
mv -- "$f" "Mijn-Video-${BASH_REMATCH[1]}.$ext"
De -- vertelt mv dat hierna geen opties meer volgen.
Dat is een kleine maar nuttige veiligheidsmaatregel. Wanneer een bestandsnaam bijvoorbeeld met een - begint, zou een programma die naam anders mogelijk als een optie kunnen interpreteren.
Ook de aanhalingstekens rond "$f" zijn belangrijk. Hierdoor worden bestandsnamen met spaties correct behandeld.
Waarom eerst een proefrun?
Wanneer je tientallen of zelfs honderden bestanden automatisch gaat hernoemen, kan een fout in een commando veel werk veroorzaken.
Daarom gebruiken we eerst:
echo
Je ziet dan precies:
oude-bestandsnaam -> nieuwe-bestandsnaam
zonder dat er daadwerkelijk iets wordt gewijzigd.
Pas wanneer alles klopt, gebruiken we:
mv
om de bestanden echt te hernoemen.
Tot slot
De Linux-terminal is niet alleen handig voor ingewikkeld serverbeheer. Ook eenvoudige dagelijkse klusjes kunnen er een stuk sneller mee.
Heb je bijvoorbeeld een complete map met videobestanden die allemaal volgens hetzelfde patroon zijn genoemd, dan kan een klein Bash-script behoorlijk wat handmatig werk besparen.
Zoals we hebben gezien, kunnen bestandsnamen verschillende notaties gebruiken. Het ene bestand bevat bijvoorbeeld S02E01, terwijl een ander 2x01 gebruikt. Controleer daarom eerst welk patroon jouw bestanden gebruiken en pas het script daarop aan.
En misschien wel de belangrijkste gewoonte bij dit soort bulkbewerkingen:
Eerst controleren met een proefrun, daarna pas uitvoeren.

