|
| BASH: script til systematisk rename Fra : Niels Andersen |
Dato : 13-12-01 16:10 |
|
Jeg bøvler med et script, og kan mærke at jeg tænker virkelig til at lære
bash ordentligt... :)
Formålet med scriptet:
Nogle filer skal renames til <prefix><nummer><postfix>, hvor nummeret skal
være fortløbende. Rækkefølgen kommer ved at sortere filerne i alfabetisk
rækkefølge.
De originale filnavne er uvedkommende, de kan være navngivet efter mange
forskellige systemer. Hovedsagen er, at rækkefølgen er enten alfabetisk,
eller ligegyldig. :)
Antal cifre i nummeret skal være ens, der skal altså være foran-stillede
nuller. Det ville være fint, hvis scriptet selv kunne finde ud af, hvor
mange der nødvendigt, men det er meget *lidt* vigtigt. :)
Jeg er kommet så langt:
#!/bin/bash
PATTERN=$1
PREFIX=$2
POSTFIX=$3
LENGTH=$4
i=0
for a in `ls $PATTERN`
do
echo cp "$a" "$PREFIX$i$POSTFIX"
((i++))
done
Jeg har sat "echo" foran linjen med cp, for bedre at kunne debugge. :)
Jeg gør så fx. sådan her:
../script.sh *.jpg directory/anim .jpg 5
Selve linjen med "cp" giver helt forkerte resultater. Fx:
$ ./test.sh *.jpg x .jpg
cp file0.jpg file1.jpg0file2.jpg
Og kun den ene linje, selv om der er 10 filer.
Desuden *aner* jeg ikke hvordan jeg skal lave tricket med foran-stillede
nuller.
Og gode råd derud over modtages gerne. :)
(Ud over at læse nogle bash-tutorials osv. Det skal jeg nok gøre senere *s*)
--
Mvh.
Niels Andersen
| |
Dennis Jørgensen (13-12-2001)
| Kommentar Fra : Dennis Jørgensen |
Dato : 13-12-01 16:23 |
|
Niels Andersen (niels-usenet@myplace.dk) wrote:
>Jeg gør så fx. sådan her:
>./script.sh *.jpg directory/anim .jpg 5
>
>Selve linjen med "cp" giver helt forkerte resultater. Fx:
>$ ./test.sh *.jpg x .jpg
>cp file0.jpg file1.jpg0file2.jpg
>
>Og kun den ene linje, selv om der er 10 filer.
Prøv at sætte gåseøjne om dit pattern (*.jpg). Ellers ændrer din shell
kommandoen til "./test.sh file0.jpg file1.jpg ... file9.jpg x .jpg".
Se evt. forskellen med echo "*.jpg" og echo *.jpg
Mvh.
Dennis Jørgensen
| |
Niels Andersen (13-12-2001)
| Kommentar Fra : Niels Andersen |
Dato : 13-12-01 17:24 |
|
"Dennis Jørgensen" <postmaster@q.nospam.kampsax.k-net.dk> wrote in message
news:slrna1hhv4.he9.postmaster@clouseau.kampsax.dtu.dk...
> Prøv at sætte gåseøjne om dit pattern (*.jpg). Ellers ændrer din shell
> kommandoen til "./test.sh file0.jpg file1.jpg ... file9.jpg x .jpg".
Argh, silly me. Selvfølgelig... :)
Men hvad med foranstillede nuller?
--
Mvh.
Niels Andersen
| |
Peter Dalgaard BSA (13-12-2001)
| Kommentar Fra : Peter Dalgaard BSA |
Dato : 13-12-01 18:14 |
|
"Niels Andersen" <niels-usenet@myplace.dk> writes:
> "Dennis Jørgensen" <postmaster@q.nospam.kampsax.k-net.dk> wrote in message
> news:slrna1hhv4.he9.postmaster@clouseau.kampsax.dtu.dk...
> > Prøv at sætte gåseøjne om dit pattern (*.jpg). Ellers ændrer din shell
> > kommandoen til "./test.sh file0.jpg file1.jpg ... file9.jpg x .jpg".
>
> Argh, silly me. Selvfølgelig... :)
>
> Men hvad med foranstillede nuller?
Prøv
echo foo`printf %010d 7913`.bar
--
O__ ---- Peter Dalgaard Blegdamsvej 3
c/ /'_ --- Dept. of Biostatistics 2200 Cph. N
(*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907
| |
Niels Andersen (13-12-2001)
| Kommentar Fra : Niels Andersen |
Dato : 13-12-01 18:19 |
|
"Peter Dalgaard BSA" <p.dalgaard@biostat.ku.dk> wrote in message
news:x2y9k7rqk9.fsf@blueberry.kubism.ku.dk...
> > Men hvad med foranstillede nuller?
> echo foo`printf %010d 7913`.bar
Yep, det er lige det, jeg søger.
*pille-pille-pille*
Dette virker:
#!/bin/bash
PATTERN=$1
PREFIX=$2
POSTFIX=$3
LENGTH=$4
i=0
for a in `ls $PATTERN`
do
echo cp "$a" "$PREFIX"`printf %0"$LENGTH"d $i`"$POSTFIX"
((i++))
done
Ja, det virker, mere positivt er det vist ikke, at sige om det.
(Nårjo, jeg lærte lidt mere om bash)
Tak for hjælpen. :)
--
Mvh.
Niels Andersen
| |
Dennis Jørgensen (13-12-2001)
| Kommentar Fra : Dennis Jørgensen |
Dato : 13-12-01 18:19 |
|
Niels Andersen (niels-usenet@myplace.dk) wrote:
>
>Men hvad med foranstillede nuller?
>
Måske noget i retning af
text = $i
while[$LENGTH -gt ${#text}]; do
text=0$text
done
?
Hvis LENGTH altså er antallet af cifre der skal være.
Eller findes der noget der kan det samme som "x" i Perl?
Mvh.
Dennis Jørgensen
| |
Niels Andersen (13-12-2001)
| Kommentar Fra : Niels Andersen |
Dato : 13-12-01 18:45 |
|
"Niels Andersen" <niels-usenet@myplace.dk> wrote in message
news:Zx3S7.3210$Q3.426214@news010.worldonline.dk...
Øv, der var et problem mere.
for a in `ls $PATTERN`
Hvis der er mellemrum i et filnavn, tror den det er flere filer. Den
splitter altså ved mellemrum.
Hvis en fil hedder "flere ord" bliver det altså til:
cp: cannot stat `flere': No such file or directory
cp: cannot stat `ord': No such file or directory
Hvad hulen gør man så?
Scriptet ser nu sådan ud:
(Jeg tillader mig lige at vise hele scriptet, i håbet om at få kommentarer
til forbedringer)
#!/bin/bash
PATTERN=$1
PREFIX=$2
POSTFIX=$3
LENGTH=$4
echo "Kopierer nu `ls $PATTERN | wc -l` filer."
i=0
for a in `ls $PATTERN`
do
cp $a "$PREFIX"`printf %0"$LENGTH"d $i`"$POSTFIX"
((i++))
echo -n -e "$i filer kopieret...\\015"
done
echo -e "\\012Done."
--
Mvh.
Niels Andersen
| |
Peppe (13-12-2001)
| Kommentar Fra : Peppe |
Dato : 13-12-01 18:50 |
|
Således berettede Niels Andersen <niels-usenet@myplace.dk>
> Hvis der er mellemrum i et filnavn, tror den det er flere filer. Den
> splitter altså ved mellemrum.
Hvis du ikke har filer med newline i, kan du prøve at sætte IFS selv:
OIFS="$IFS"
IFS="
"
Peppe
--
"Before you criticize someone, walk
Preben "Peppe" Guldberg __/-\__ a mile in his shoes. That way, if
c928400@student.dtu.dk (o o) he gets angry, he'll be a mile away
----------------------oOOo (_) oOOo-- - and barefoot." --Sarah Jackson
| |
Kent Friis (13-12-2001)
| Kommentar Fra : Kent Friis |
Dato : 13-12-01 19:08 |
|
Den Thu, 13 Dec 2001 18:44:35 +0100 skrev Niels Andersen:
>"Niels Andersen" <niels-usenet@myplace.dk> wrote in message
>news:Zx3S7.3210$Q3.426214@news010.worldonline.dk...
>Øv, der var et problem mere.
>
>for a in `ls $PATTERN`
>
>Hvis der er mellemrum i et filnavn, tror den det er flere filer. Den
>splitter altså ved mellemrum.
>
>Hvis en fil hedder "flere ord" bliver det altså til:
>cp: cannot stat `flere': No such file or directory
>cp: cannot stat `ord': No such file or directory
>
>Hvad hulen gør man så?
Jeg ville gøre det på en hel anden måde:
>#!/bin/bash
>
>PATTERN=$1
>PREFIX=$2
>POSTFIX=$3
>LENGTH=$4
PREFIX="$1" # Ja, jeg bytter lige rundt på dine parametre...
POSTFIX="$2"
LENGTH="$3"
shift 3 # Smid de tre første parametre væk
>echo "Kopierer nu `ls $PATTERN | wc -l` filer."
echo "Kopierer nu $(ls "$@" | wc -l) filer." # $() er mere læsevenlig
>i=0
>for a in `ls $PATTERN`
for a in "$@" # alle parametre
>do
>cp $a "$PREFIX"`printf %0"$LENGTH"d $i`"$POSTFIX"
cp "$a" "$PREFIX$(printf %0${LENGTH}d $i)$POSTFIX"
>((i++))
# WTF? Den havde jeg ikke set før.
>echo -n -e "$i filer kopieret...\\015"
>done
>
>echo -e "\\012Done."
Mvh
Kent
--
http://www.celebrityshine.com/~kfr/
| |
Niels Andersen (13-12-2001)
| Kommentar Fra : Niels Andersen |
Dato : 13-12-01 19:36 |
|
"Kent Friis" <kfr@fleggaard.dk> wrote in message
news:9vaqqc$cjm$1@sunsite.dk...
> Jeg ville gøre det på en hel anden måde:
Og den måde virker helt perfekt. :)
Og tak for alle de små rettelser, jeg har kigget nøje på dem, og tror jeg
forstår dem alle. :)
Og mht. denne:
((i++))
Det var den simpleste måde jeg kunne finde (på), til at forhøje $i med én.
:)
--
Mvh.
Niels Andersen
| |
Kent Friis (13-12-2001)
| Kommentar Fra : Kent Friis |
Dato : 13-12-01 19:58 |
|
Den Thu, 13 Dec 2001 19:35:30 +0100 skrev Niels Andersen:
>"Kent Friis" <kfr@fleggaard.dk> wrote in message
>news:9vaqqc$cjm$1@sunsite.dk...
>> Jeg ville gøre det på en hel anden måde:
>
>Og den måde virker helt perfekt. :)
>
>Og tak for alle de små rettelser, jeg har kigget nøje på dem, og tror jeg
>forstår dem alle. :)
>
>Og mht. denne:
>((i++))
>Det var den simpleste måde jeg kunne finde (på), til at forhøje $i med én.
>:)
Jeg plejer at bruge:
i=$((i+1))
Det ser ud til at ((i++)) kun virker i bash. ksh på HP/UX-maskinen ville
i hvert fald ikke æde den.
Mvh
Kent
--
http://www.celebrityshine.com/~kfr/
| |
Peter Dalgaard BSA (13-12-2001)
| Kommentar Fra : Peter Dalgaard BSA |
Dato : 13-12-01 22:50 |
|
kfr@fleggaard.dk (Kent Friis) writes:
> Jeg plejer at bruge:
> i=$((i+1))
>
> Det ser ud til at ((i++)) kun virker i bash. ksh på HP/UX-maskinen ville
> i hvert fald ikke æde den.
Aritmetik virker som hovedregel ikke i shells, derfor ses
konstruktioner som
i=`expr $i + 1`
eller (i oldtiden)
i=`echo $i 1 + p | dc`
--
O__ ---- Peter Dalgaard Blegdamsvej 3
c/ /'_ --- Dept. of Biostatistics 2200 Cph. N
(*) \(*) -- University of Copenhagen Denmark Ph: (+45) 35327918
~~~~~~~~~~ - (p.dalgaard@biostat.ku.dk) FAX: (+45) 35327907
| |
frank damgaard (13-12-2001)
| Kommentar Fra : frank damgaard |
Dato : 13-12-01 23:06 |
|
Peter Dalgaard BSA <p.dalgaard@biostat.ku.dk> wrote:
> Aritmetik virker som hovedregel ikke i shells, derfor ses
> konstruktioner som
> i=`expr $i + 1`
> eller (i oldtiden)
> i=`echo $i 1 + p | dc`
Eller "let" i bash :
i=2
let i=i+1
Det er dog kun heltal, men det er bash specifik...
--
no signature :)
| |
Michael Hjorth (17-12-2001)
| Kommentar Fra : Michael Hjorth |
Dato : 17-12-01 00:25 |
|
frank damgaard wrote:
>
> Peter Dalgaard BSA <p.dalgaard@biostat.ku.dk> wrote:
>
> > Aritmetik virker som hovedregel ikke i shells, derfor ses
> > konstruktioner som
>
> > i=`expr $i + 1`
>
> > eller (i oldtiden)
>
> > i=`echo $i 1 + p | dc`
>
> Eller "let" i bash :
>
> i=2
> let i=i+1
>
> Det er dog kun heltal, men det er bash specifik...
Hvis du bruger typeset så kan du slippe for lidt parenteser og samtidig
få et script som virker i både ksh og bash:
typeset -i i
i=2
i=$i+1
Michael.
| |
Niels Andersen (14-12-2001)
| Kommentar Fra : Niels Andersen |
Dato : 14-12-01 08:51 |
|
"Peter Dalgaard BSA" <p.dalgaard@biostat.ku.dk> wrote in message
news:x2y9k694dv.fsf@blueberry.kubism.ku.dk...
> > Det ser ud til at ((i++)) kun virker i bash. ksh på HP/UX-maskinen ville
> > i hvert fald ikke æde den.
> Aritmetik virker som hovedregel ikke i shells, derfor ses
> konstruktioner som
> i=`expr $i + 1`
Jeg tror jeg vil prøve at huske denne. :)
I dette specifikke script VED jeg, at det altid er bash der bliver brugt. :)
--
Mvh.
Niels Andersen
| |
Claus Rasmussen (14-12-2001)
| Kommentar Fra : Claus Rasmussen |
Dato : 14-12-01 09:02 |
|
Niels Andersen wrote:
> "Peter Dalgaard BSA" <p.dalgaard@biostat.ku.dk> wrote in message
>
>> i=`expr $i + 1`
>
> Jeg tror jeg vil prøve at huske denne. :)
Den er ok at huske, men dum at bruge. Husk den fordi, du måske en dag
sidder ved en-eller-anden oldnordisk maskine, som ikke har den nyere
konstruktion, men lad være med at bruge den, fordi det andet efterhånden
er ved at blive standard. Det samme gælder backquotes "`" vs. "$()".
Hvis du vide, hvad der er standard, er bash et godt udgangspunkt. Ellers
kan du kigge på ksh (Korn shell).
-Claus
| |
Kent Friis (14-12-2001)
| Kommentar Fra : Kent Friis |
Dato : 14-12-01 16:18 |
|
Den Fri, 14 Dec 2001 08:50:30 +0100 skrev Niels Andersen:
>"Peter Dalgaard BSA" <p.dalgaard@biostat.ku.dk> wrote in message
>news:x2y9k694dv.fsf@blueberry.kubism.ku.dk...
>> > Det ser ud til at ((i++)) kun virker i bash. ksh på HP/UX-maskinen ville
>> > i hvert fald ikke æde den.
>> Aritmetik virker som hovedregel ikke i shells, derfor ses
>> konstruktioner som
>> i=`expr $i + 1`
>
>Jeg tror jeg vil prøve at huske denne. :)
>
>I dette specifikke script VED jeg, at det altid er bash der bliver brugt. :)
i=$(($i+1)) er ikke bash-specifik (ksh har den, jeg ved ikke med Bourne
shell), og den er meget hurtigere end at kalde et eksternt program (expr
eller dc).
Mvh
Kent
--
http://www.celebrityshine.com/~kfr/
| |
|
|