/ Forside / Teknologi / Operativsystemer / Linux / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Linux
#NavnPoint
o.v.n. 11177
peque 7911
dk 4814
e.c 2359
Uranus 1334
emesen 1334
stone47 1307
linuxrules 1214
Octon 1100
10  BjarneD 875
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/

Søg
Reklame
Statistik
Spørgsmål : 177513
Tips : 31968
Nyheder : 719565
Indlæg : 6408603
Brugere : 218887

Månedens bedste
Årets bedste
Sidste års bedste