Jeg vil omdøbe flere filer i samme bibliotek ved hjælp af Bash-scripting. Filernes navne er som følger:
file2602201409853.p file0901201437404.p file0901201438761.p file1003201410069.p file2602201410180.p
Jeg vil omdøbe til følgende format:
file2503201409853.p file2503201437404.p file2503201438761.p file2503201410069.p file2503201410180.p
Jeg læste om kommandoen omdøb, og prøv at gøre det på denne måde, men det gør ingenting, jeg tror, jeg har spørgsmål om syntaksen. Så læste jeg, at du kan lave en løkke ved hjælp af 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 omdøbe filerne. Hvad laver jeg forkert?
Kommentarer
Svar
Du havde ret i at overveje at omdøbe først. Syntaksen er lidt underlig, hvis du ikke er vant til at regexere, men det er langt den hurtigste / korteste rute, når du først ved, hvad du laver:
rename "s/\d{4}/2503/" file*
Det matcher simpelthen de første 4 tal og bytter dem til dem, du har angivet.
Og en testsele (-vn
betyder at være verbose men ikke “t gør hvad som helst) ved hjælp af dine filnavne:
$ 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
- Bemærk at dette er Perl-omdøbet på Debian og derivater (Ubuntu, Mint, …). På andre Linux-distributioner er
rename
et helt andet filomdøbningsværktøj (som Debian sendes somrename.ul
). - Hvis din distribuerende mangel på et sådant værktøj, se på @Michael Campbell svar. Jeg tror, at hver distributør erstatter standard
rename
som debian gjorde.
Svar
Dette skal gøre tricket:
for f in file*; do mv $f ${f/${f:4:8}/25032014}; done
Det erstatter strengen mellem 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 nice. Hvis du bare vil lave et ord for ordudskiftning, fungerer det som sed. for eksempel.
for f in *Huge*; do mv $f ${f/Huge/Monstrous}; done
- @Eric – Jeg sendte dit svar som et alternativ, fordi jeg synes, det ' er mere klart og elegant . Hvis du også vil sende det som et svar – Jeg ' sletter mit. Tak!
- Hvorfor mangler dobbelt citater ?
- Det giver mig en fejl: " mv: target ' FILE_NAME ' er ikke et bibliotek "
Svar
dette er virkelig @Erics svar ovenfra – men det er et elegant svar så Jeg sender det igen som et korrekt svar for at henlede mere opmærksomhed på 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 skulle gøre tricket. Bemærk – Jeg er ikke vant til at aflevere masse-mv-kommandoer – som skrevet er det bare et ekko. Du” Jeg bliver nødt til at ordne det, før det “fungerer.
Svar
En enkel, indfødt måde at gøre det på uden looping, med bibliotekstrafik :
find -type f | xargs -I {} mv {} {}.txt
Det omdøber hver fil på plads.
Og under et værk ing eksempel med parallelisering :
find -name "file*.p" | parallel "f="{}" ; mv -- {} ${f:0:4}2503${f:8}"
Kommentarer
- Det var en let første tilgang at forestille sig en bedre løsning. Hvis du vil have en fungerende kommando, skal du gøre:
-
find -type f -name "file*.p" | parallel 'ext="{}" ; mv -- {} ${ext:0:4}2503${ext:8}'
Svar
Hvis du finder ud af, at du gør denne slags ting meget, skal du slå “rename.pl” op. Det er et perl-script, men giver dig mulighed for simpelthen at føje det til perl-kode (som /// expression), og det vil omdøbe massen baseret på dette udtryk eller kode.
Der er en grundlæggende version her: http://stackoverflow.org/wiki/Rename.pl , men der er andre versioner, der flyder rundt på nettet. Det har eksisteret i aldre og aldre og aldre.
*
er?