Jeg vil gi nytt navn til flere filer i samme katalog ved hjelp av Bash-skripting. Filenes navn er som følger:
file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p
Jeg vil gi nytt navn til følgende format:
file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p
Jeg leste om navnet på kommandoen, og prøv å gjøre det på denne måten, men det gjør ingenting, jeg tror jeg har spørsmål om syntaksen. Så leste jeg at du kan lage en løkke ved hjelp av mv -kommandoen som følger:
for file in cmpsms*2014*.p; do mv "$file" "${file/cmpsms*2014*.p/cmpsms25032014*.p}" done
Men jeg kan ikke gi nytt navn til filene. Hva gjør jeg galt?
Kommentarer
Svar
Du hadde rett i å vurdere å gi nytt navn først. Syntaksen er litt rart hvis du ikke er vant til å regexere, men det er den raskeste / korteste ruten når du vet hva du gjør:
rename "s/\d{4}/2503/" file*
Det samsvarer ganske enkelt med de første 4 tallene og bytter dem mot de du har angitt.
Og en testsele (-vn
betyr å være ordentlig, men ikke gjør hva som helst) ved hjelp av filnavnene dine:
$ 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
Kommentarer
- Merk at dette er Perl-navnet på Debian og derivater (Ubuntu, Mint, …). I andre Linux-distribusjoner er
rename
et helt annet verktøy for filnavn (som Debian sendes somrename.ul
). - Hvis din distributive mangel på et slikt verktøy, se på @Michael Campbell svar. Jeg tror hver distributør erstatter standard
rename
som debian gjorde.
Svar
Dette skal gjøre susen:
for f in file*; do mv $f ${f/${f:4:8}/25032014}; done
Den erstatter strengen mellom 4. og 12. tegn med «25032014».
Kommentarer
- denne
for f in file*; do mv $f ${f/${f:4:4}/2503}; done
fungerer også. - At ' s hyggelig. Hvis du bare vil gjøre et vanlig ord for ordutskiftning, fungerer det som sed. f.eks.
for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
- @Eric – Jeg la ut svaret ditt som et alternativ fordi jeg tror det ' er mer tydelig og elegant . Hvis du også vil legge det ut som svar – Jeg ' sletter mitt. Takk!
- Hvorfor mangler dobbelt anførselstegn ?
- Det gir meg en feil: " mv: target ' FILE_NAME ' er ikke en katalog "
Svar
dette er virkelig @Erics svar ovenfra – men det er et elegant svar så Jeg legger ut det som et riktig svar for å trekke mer oppmerksomhet til det.
for f in *Huge*; do mv "$f" "${f/Huge/Monstrous}"; done
Svar
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 )
Dette skal gjøre susen. Merk – Jeg har ikke for vane å overlevere masse-mv-kommandoer – som skrevet er det bare et ekko. Du» Jeg må ordne det før det vil fungere.
Svar
En enkel innfødt måte å gjøre det uten å løkke, med katalogtrafikk :
find -type f | xargs -I {} mv {} {}.txt
Det vil gi nytt navn til hver filen på plass.
Og under et verk ing eksempel med parallellisering :
find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}"
Kommentarer
- Det var en enkel første tilnærming å forestille seg en bedre løsning. Hvis du vil ha en fungerende kommando, gjør:
-
find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
Svar
Hvis du finner ut at du gjør denne typen ting mye, slå opp «rename.pl». Det er et perl-skript, men lar deg bare mate det perl-koden (som /// expression), og det vil gi et massenavn basert på det uttrykket eller koden.
Det er en grunnleggende versjon her: http://stackoverflow.org/wiki/Rename.pl men det er andre versjoner som flyter rundt på nettet. Det har eksistert i evigheter og aldre.
*
er?