Hernoem meerdere bestanden met Bash-scripting

Ik wil meerdere bestanden in dezelfde directory hernoemen met behulp van Bash-scripting. De namen van de bestanden zijn als volgt:

file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p 

Ik wil de naam wijzigen naar het volgende formaat:

file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p 

Ik las over het hernoemen commando, en probeer het op deze manier te doen, maar het doet niets, ik denk dat ik vragen heb over de syntaxis. Toen las ik dat je een lus kunt maken met de opdracht mv als volgt:

for file in cmpsms*2014*.p; do mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}" done 

Maar ik kan de bestanden niet hernoemen. Wat doe ik verkeerd?

Reacties

  • mogelijk duplicaat van Hoe kan ik veel hernoemen van bestanden die een regex gebruiken?
  • U kunt ' geen patroomexpressie aan de rechterkant van een vervangende expressie voor parameteruitbreiding hebben. Wat had je verwacht te zijn waar dat * is?
  • @Kiwy Die vraag gaat over het verwijderen van een deel van de bestandsnaam. Ergo, hoogst twijfelachtig duplicaat.
  • Beschrijf de volgende keer de wijzigingen in de bestandsnaam die u wilt maken (ik moest hier een tijdje naar kijken voordat ik de verschillen en overeenkomsten zag). Voorbeelden zijn goed, maar een beschrijving van zowel als voorbeelden is zelfs nog beter.

Antwoord

Je had gelijk om eerst te overwegen om de naam te wijzigen. De syntaxis is een beetje vreemd als je “niet gewend bent aan regex, maar het is verreweg de snelste / kortste route als je eenmaal weet wat je” doet:

rename "s/\d{4}/2503/" file* 

Dat komt gewoon overeen met de eerste 4 cijfers en verwisselt ze voor de getallen die je hebt opgegeven.

En een testharnas (-vn betekent uitgebreid zijn, maar alles doen ) met uw bestandsnamen:

$ rename "s/\d{4}/2503/" file* -vn file0901201437404.p renamed as file2503201437404.p file0901201438761.p renamed as file2503201438761.p file1003201410069.p renamed as file2503201410069.p file2602201409853.p renamed as file2503201409853.p file2602201410180.p renamed as file2503201410180.p 

Reacties

  • Opmerking dat dit de Perl-hernoeming is op Debian en derivaten (Ubuntu, Mint,…). Op andere Linux-distributies is rename een compleet andere tool voor het hernoemen van bestanden (die Debian verzendt als rename.ul).
  • Als je distributieve gebrek aan zon tool hebt, kijk dan naar @Michael Campbell antwoord. Ik denk dat elke distributieve standaard rename vervangt zoals Debian deed.

Answer

Dit zou de slag moeten slaan:

for f in file*; do mv $f ${f/${f:4:8}/25032014}; done 

Het vervangt de tekenreeks tussen het 4e en het 12e teken door “25032014”.

Opmerkingen

  • dit for f in file*; do mv $f ${f/${f:4:4}/2503}; done werkt ook.
  • Dat ' is leuk. Als je gewoon een normaal woord voor woordvervanging wilt doen, werkt het als sed. bijv. for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
  • @Eric – Ik heb je antwoord als alternatief gepost omdat ik denk dat het ' duidelijker en eleganter is . Als je het ook als antwoord wilt posten – ik ' zal de mijne verwijderen. Bedankt!
  • Waarom ontbreken in de dubbele aanhalingstekens ?
  • Ik krijg een foutmelding: " mv: target ' FILE_NAME ' is geen directory "

Antwoord

dit is echt het antwoord van @Eric van bovenaf – maar het is een elegant antwoord dus Ik plaats het opnieuw als een juist antwoord om er meer aandacht op te vestigen.

for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done 

Answer

ptrn="file[0-9][0-9][0-9][0-9]2014[0-9][0-9][0-9][0-9][0-9].p" path=/dir ( set -- "${path}/"${ptrn} ; for f ; do { echo "mv ${path}/${f} \ ${path}/file25032014${f#2014}" } ; done ) 

Dit zou moeten werken. Opmerking – ik” heb niet de gewoonte om massa-mv-commandos over te dragen – zoals geschreven is het maar een echo. Jij ” Ik zal dat uitzoeken voordat het “ll werkt.

Antwoord

Een eenvoudige native manier om het te doen zonder te herhalen, met directory-traversal :

find -type f | xargs -I {} mv {} {}.txt 

Het zal elke bestand op zijn plaats.

En onder een werk voorbeeld met parallellisatie :

find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}" 

Reacties

  • Het was een gemakkelijke eerste benadering om een betere oplossing te bedenken. Als je een werkend commando wilt, doe dan:
  • find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'

Antwoord

Als je merkt dat je dit soort dingen vaak doet, zoek dan “rename.pl” op. Het is een perl-script, maar je kunt het gewoon perl-code invoeren (zoals als /// expressie), en het zal een massa hernoemen op basis van die expressie of code.

Er is een basisversie hier: http://stackoverflow.org/wiki/Rename.pl maar er zijn andere versies die over het net zweven. Het bestaat al eeuwen en eeuwen en eeuwen.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *