Annons

Linux shell-skript

Produkter
(logga in för att koppla)

raderad12

Aktiv medlem
Hej alla Linux-nördar som fotograferar.

Jag tänkte att jag skulle starta en tråd där vi som kör Linux delar med oss av våra små finurliga shell-skript som vi har. Beskriv helt kort vad skriptet gör och om det är beroende av att något udda är installerat, gärna en länk till det programmet. Klistra sedan in det i en "code" tagg i ditt bidrag till denna tråd. Observera att du måste radbryta långa rader i ditt skript med en backlash "\", annars vill gärna fotosidans forumdesign "gå sänder", bryt vid ca 65 tecken. Till er som vill testa skripten så är rådet att testa dem på några kopior av era filer, det kan ju vara fel och buggar på det som klistras in i denna tråd, så en viss försiktighet råder jag er till.

Jag börjar nedan med ett fil-namnbytes-skript, som tar datumet från fotograferingsögonblicket ur Exif och lägger detta först i filnamnet. Skriptet ändrar filnamn på alla CRW (Canon) och JPG filer i aktuell katalog, det är alltså ämnat för Canon och i CRW fallet förutsätter det att THM filerna finns kvar (de innehåller Exif infon). Detta skript förutsätter givetvis också att libexif med sitt tillhörande kommando exif finns installerat.
Källkod:
#!/bin/bash
#
for i in *.crw *.jpg; do
if echo "$i" | grep -q ".crw"; then 
EXFIL=${i%crw}thm
FILNAMN=${i#crw}
else 
EXFIL=$i
FILNAMN=${i#img}
fi
DATUM=`exif -t 0x9003 $EXFIL | sed -e 's/Value: //;s/://g;$!d' | \
awk '{print $1}'`
mv $i $DATUM$FILNAMN
done
 
Här ett skript som använder ImageMagicks convert kommando för att skala ned och rama in en bild och sätta en "vattenstämpel" med fotografens namn. Observera att detta skript skriver över orginalbilden om filnamnet slutar på .jpg, så använd detta på en kopia. Jag bifogar en bild på resultatet av detta skript. Skriptet används, exempel: ./skriptnamn.sh filnamn.tif
Källkod:
#!/bin/bash
#
in=$1
ut=${in%.*}.jpg
convert -scale x250 -filter Lanczos -unsharp 0x0.9+1.10+0.03 \
-border 2x2 -bordercolor black \
-font helvetica -pointsize 14 -draw "gravity SouthEast \
fill black text 7,12 'Foto: Magnus Stålnacke ' \
fill #aaa text 8,11 'Foto: Magnus Stålnacke ' " \
-border 1x1 -bordercolor grey \
-frame 4x4 -mattecolor black \
-quality 76 $in $ut
 

Bilagor

  • img_1924.jpg
    img_1924.jpg
    23.5 KB · Visningar: 3,621
Detta skript konverterar en råfil med dcraw till en 16-bitars TIFF med profilhantering genom LittleCMS via ImageMagicks kommando convert. Modifiera bara med rätt sökvagar till till dina profiler. Du behöver en någorlunda färsk version av dcraw som tar -m växeln.
Källkod:
#!/bin/bash
#
TF=${1%.*}.tif
dcraw -c -m -4 -w $1 | \
convert -intent perceptual -profile /din/kameraprofil.icc \
-profile /din/utprofil.icc \
pnm:- +profile '*' tif:- > $TF
 
Skala ned - rama in

Hej Magnus!

Jag är nybörjare på linux och finner nya roliga saker hela tiden
Tack för ditt fina skala ned rama in script
Funkar kalasbra!

Först fick jag ett felmeddelande:
"convert: unable to read font `/usr/share/fonts/type1/gsfonts/n019003l.pfb'."

Då jag inte "fotobehandlat" i min linuxkärra förut
saknade jag lite paket:
libexif10
exif
gsfonts
(Hade Imagemagick redan)
men efter ha blåst in de (fanns som färdiga paket på debian.org till min amd64, funkade det klockrent.

Tack igen och kom gärna med mer nyttiga tips.
 
Webalbum-skript

Tack Marcus, alltid roligt med lite feedback.

Här kommer ett lite längre skript, som gör webbalbum av alla jpeg i aktuell katalog (orginalfilerna flyttas till en katalogen kamera som skapas). Det kopierar skalar och skärper, gör klickbara tumnaglar, gör html-sidor med länkar till nästa och föregående bild, en stilmall och en indexsida. Det vart lite bökigare än jag trodde att hålla ned radlängderna i detta skript, men det borde funka nu. Detta skript är en nedbantad version av ett annat större skript jag har som även hanterar Exif och råfiler.
Källkod:
#!/bin/bash
#
mkdir thumbs 
mkdir web 
mkdir kamera
echo 'Skalar och kopierar...'
for i in *.jpg; do
echo "$i -- done"
convert -scale 700 -unsharp 0x0.9+0.98+0.03 -quality 80 \
$i web/$i
convert -scale 200 -unsharp 0x0.9+1.1+0.03 -quality 80 \
$i thumbs/$i
done 
mv *.jpg kamera
echo 'Skapar html filer...'
cd web
for i in *.jpg; do 
htm=${i%jpg}html
echo '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html>
<head>''' > $htm
echo \<title\>$i\</title\> >> $htm
echo \<meta http-equiv=\"Content-Type\" content=\"text/html\" \
charset=\"ISO-8859-1\"\> >> $htm
echo \<link href=\"../stil.css\" rel=\"stylesheet\" \
type=\"text/css\"\> >> $htm
echo '''</head\>
<body>''' >> $htm
GEO=`identify $i | awk '{print $3}'`
IW=`echo $GEO | sed 's/[^0-9]/ /g' | awk '{print $1}'`
IH=`echo $GEO | sed 's/[^0-9]/ /g' | awk '{print $2}'`
echo \<img src=\"$i\" width=\"$IW\" height=\"$IH\" \
alt='""'\>\ >> $htm
NU=`ls -1 *.jpg | grep -A 1 -B 1 $i`
PRV=`echo $NU | sed 's/jpg/html /g' | awk '{print $1}'`
NXT2=`echo $NU | sed 's/jpg/html /g' | awk '{print $2}'`
NXT=`echo $NU | sed 's/jpg/html/g' | awk '{print $3}'`
if [ "$htm" != "$PRV" ] 
then echo \<p\>\<a href=\"$PRV\"\>Föregående\</a\> -- >> $htm 
else echo \<p\>Föregående -- >> $htm
fi
echo '<a href="../album.html">Index</a> --' >> $htm; 
SISTA=`ls -1 *.jpg | tail -n 1`
if [ $SISTA == $i ]
then echo Nästa\</p\> >> $htm
elif [ "$htm" != "$PRV" ] 
then echo \<a href=\"$NXT\"\>Nästa\</a\>\</p\> >> $htm
else echo \<a href=\"$NXT2\"\>Nästa\</a\>\</p\> >> $htm
fi
echo '</body>' >> $htm
echo '</html>' >> $htm
done 
cd .. 
echo 'Skapar index-album'
echo '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<html\>
<head\>
<title>Album</title>''' > album.html
echo \<meta http-equiv=\"Content-Type\" content=\"text/html\" \
charset=\"ISO-8859-1\"\> >> album.html
echo \<link href=\"stil.css\" rel=\"stylesheet\" \
type=\"text/css\"\> >> album.html
echo '''</head\>
<body>
<div id="main"\>''' >> album.html
cd thumbs
for i in *.jpg; do 
GEO=`identify $i | awk '{print $3}'`
IW=`echo $GEO | sed 's/[^0-9]/ /g' | awk '{print $1}'`
IH=`echo $GEO | sed 's/[^0-9]/ /g' | awk '{print $2}'`
htm=${i%jpg}html
echo \<a href=\"web/$htm\"\>\<img src=\"thumbs/$i\" \
width=\"$IW\" height=\"$IH\" alt=\"\"\>\</a\> >> ../album.html
done
cd ..
echo '''</div>
</body>
</html>''' >> album.html
echo 'Skapar stilmall'
echo '''body {text-align:center; background:#000; color:#fff;}
img {border:1px solid #fff; margin:10px 5px 10px 5px;}
a {color:#ddf; background:transparent; font-weight:bold;}
a:hover {color:#f00; background:transparent;}
#main {width:82%; border:1px solid #fff; margin:0px auto;}
p {font-family:sans-serif;}''' > stil.css
echo 'Album klart'
 
Hej Magnus ett mycket bra initiativ!

Ska försöka att bidra med något script vad det lider.

/Micke
 
Här kommer en litet perl-skript som tar filerna i ett directory, plockar ut fotograferingsdatumet och lägger dem i underdirectoryn med namn av typen ÅÅMMDD. Det är så jag brukar sortera mina bilder och det är praktiskt att automatisera det hela. Just detta skript fungerar på filer från Nikon D70 och använder d70reader, http://www.gogebic-pc.com/d70/, för att plocka ut fotograferingsdatumet. Det borde dock gå alldeles utmärkt att ändra till något annat program om man föredrar det.

Här är skriptet:

Källkod:
#!/usr/bin/perl
# Script to go through all picture files in a directory and organize them
# in folders named after capture date.
# Author: Joakim Edsjo, [email][email protected][/email]
# Date: 2006-04-10


$d70r="/usr/local/bin/d70reader";

if ($#ARGV<0) {
    die "Usage: organize-pics <directory>\n";
}

$dir=shift;

foreach $file (<$dir/*>) {
#    print "File: $file  ";
    $date=`$d70r $file | grep 'DateTimeDigitized'`;
    $date=~ s/^DateTimeDigitized\s+:\s//;
#    print "$date\n";
    ($yr,$mo,$day) = split(/\:/,$date);
    ($day) = split(/\s+/,$day);
#    print "Year: $yr\n";
#    print "Month: $mo\n";
#    print "Day: $day\n";
    $newdir=substr($yr,2,2) . $mo . $day;
    if ($newdir ne "") {
	mkdir("$dir/$newdir") if (! -d "$dir/$newdir");
	$newfile=$file;
	$newfile=~ s/^$dir/$dir\/$newdir/;
#	print "File: $file\n";
#	print "Newfile: $newfile\n";
	rename($file,$newfile);
    }
}
 
Någonsin funderat på den genomsnittliga brännvidden du använt? Följande lilla skript tar ut den genomsnittliga brännvidden du använt av alla bilder i aktuell katalog.
Källkod:
#!/bin/bash
#
ALL=`for i in *.jpg *.thm; do
exif $i | grep "Fo.*th" | sed 's/.*|//;s/,. mm//'
done`
ANT=`echo "$ALL" | wc -l`
for i in $ALL; do
let "SUM += $i"
done
expr $SUM / $ANT
 
Mer inom avdelningen onödigt vetande och statistik.. Samma som ovan fast med bländartalet istället.
Källkod:
#!/bin/bash
#
ALL=`for i in *.jpg *.thm; do
exif -i $i | grep "0x9202" | sed 's/.*|f\///'
done`
ANT=`echo "$ALL" | wc -l`
for i in $ALL; do
let "SUM += $i"
done
expr $SUM / $ANT
 
Det kanske är att svära i kyrkan, men jag tycker det är värt att tipsa alla som kör windows att den här typen av smidig automatisering inte alls är omöjlig för dem heller. Med Cygwin installerat får man ett riktigt skal och alla trevliga verktyg från *nix-världen. Det är det första jag installerar på en windowsburk. Till och med x funkar bra och de flesta program går att kompilera rakt av om de inte redan finns förpackade i cygwin.
 
Shellscripts fungerar bra på Mac också.

Jag har bara en liten invändning mot scripten som publicerats här: man bör, om möjligt, hålla sig till standard shell och inte göra scripten beroende av bash. Dels handlar det om att inte använda konstruktioner som bara finns i bash, dels handlar det om att ha #!/bin/sh (istället för #!/bin/bash) på första raden.

Sen är det förstås inte säkert att ett shellscript som fungerar bra på linux fungerar på Windows eller Mac beroende på att scriptet utnyttjar sig av program som inte finns på Windows eller Mac. (Det kan gå att installera dem, men är oftast inte helt trivialt).

PD
 
PMD skrev:
Jag har bara en liten invändning mot scripten som publicerats här: man bör, om möjligt, hålla sig till standard shell och inte göra scripten beroende av bash.

Jag förstår vad du menar (även om jag själv tycker att allt utom csh är bra). Däremot tror jag att det är mer motstånd mot att lägga upp något eget om man först måste konvertera. Inte för att det är jobbigt, utan för att det är mer jobb.
 
boran skrev:
Däremot tror jag att det är mer motstånd mot att lägga upp något eget om man först måste konvertera. Inte för att det är jobbigt, utan för att det är mer jobb.
Visst. Redan skrivna scripts är de flesta av oss ganska omotiverade att standardisera. Min uppmaning gällde mera vad man bör tänka på när man skriver nya scripts.

PD
 
Show us the code

PMD skrev:
att inte använda konstruktioner som bara finns i bash, dels handlar det om att ha #!/bin/sh (istället för #!/bin/bash) på första raden.
Det jag lagt in här är bara klipp o klistra från sådant jag skrivit utan tanke på att användas i någon annans dator.

Till alla andra - "show us the code", annars spårar tråden bara ur till mycke snack o lite verkstad.

Å bara för att inte kasta sten i glashus.. Nedan ett skript för att snabbscanna i 300ppi direkt till skrivare. I detta kan man behöva justera nivåer (mogrify kommandot) för att passa just sin skrivare/scanner. Nedan är vad som blir bra för en "snabbscanning" just för mig och mina prylar.
Källkod:
#!/bin/bash
#
sc=/tmp/scan.pnm
scanimage --mode color --resolution 300 \
--quick-format Letter > $sc
mogrify -level 15%,96% $sc
pnmtops -dpi 300 -equalpixels -nocenter -rle $sc | lpr 
rm $sc
 
Jag känner mig skyldig som pratade utan att posta ett script. Detta är väl halvrelaterat då det har med arbetsflödet att göra.
Mina framkallade jpg hamnar i en underkatalog "converted". Detta script körs från min katalog med Canon raw-filer (.crw och .thm) och tar bort de filer jag inte har brytt mig om att framkalla till jpg.

-----------------------------------
#!/usr/bin/perl -w
use strict;

open(FILELIST, "/bin/ls *.crw|");
while (my $fname = <FILELIST>){
chomp $fname;
my $jpg = my $thm = $fname;
$jpg =~ s/crw$/jpg/;
$thm =~ s/crw$/thm/;
next if ( -f "converted/$jpg");
unlink "$fname";
unlink "$thm" if ( -f "$thm");
}
-----------------------------------

Snabba Perl-hack utan vare sig felkontroller eller kommentarer är en arbetsskada. :)
 
Re: Show us the code

steelneck skrev:
Till alla andra - "show us the code", annars spårar tråden bara ur till mycke snack o lite verkstad.
OK, nedanstående använder jag för att göra en enkel webalbumsida. Gör cd katalog-med-jpeg-filer och kör sedan scriptet. Det skapar då en websida med tumnaglar, en katalog med tumnagelfilerna (hupp!) och en katalog med filer lagom för webbruk.

Det går att styra i detalj var alla olika sorters filerna hamnar genom att sätta de olika omgivningsvariablerna som syns i början av scriptet.

Källkod:
#! /bin/sh

# Requires the ImageMagick package.
# Only tested on Linux. May require fixes for other unixes.

: ${THUMBDIR_NAME=thumbs}
: ${WEBDIR_NAME=web}
: ${TITLE=TITLE}
: ${JPEGDIR=$(pwd)}
: ${WEBDIR=$JPEGDIR/$WEBDIR_NAME}
THUMBDIR=$WEBDIR/$THUMBDIR_NAME

last_item()
{
    # $*: list of JPEG files

    number_of_files=$#
    shift $(($#-1))
    last_file=$1
}

make_all_html()
{
    # $*: list of JPEG files

    first_file=$1
    previous_file=$(basename $last_file)
    for ((i=1; i <= number_of_files; i++)); do
	current_file=$(basename $1)
	shift
	if [ -z $1 ]; then
	    next_file=$first_file
	else
	    next_file=$(basename $1)
	fi
	if echo $previous_file | grep -q ".JPG$" ; then
	    previous_html=$(basename $previous_file .JPG).html
	else
	    previous_html=$(basename $previous_file .jpg).html
	fi
	if echo $current_file | grep -q ".JPG$" ; then
	    current_html=$(basename $current_file .JPG).html
	else
	    current_html=$(basename $current_file .jpg).html
	fi
	if echo $next_file | grep -q ".JPG$" ; then
	    next_html=$(basename $next_file .JPG).html
	else
	    next_html=$(basename $next_file .jpg).html
	fi

	cat <<EOF > $WEBDIR/$current_html
<HTML>
<HEAD>
<LINK REV="made" HREF="mailto:$USER@$(dnsdomainname)">
<TITLE>${TITLE}</TITLE>
<style type="text/css">
<!--
A{text-decoration:none}
-->
</style>
</HEAD>
<BODY>
<TABLE border=5 cellpadding=2%>
<TR VALIGN=bottom>
<TD ALIGN=center><A HREF=${previous_html}>Föregående bild</A></TD>
<TD><A HREF=index.html>Index</A></TD>
<TD><A HREF=${next_html}>Nästa bild</A>
</TR>
</TABLE>
<P>
<A HREF=$JPEGDIR/$(basename ${current_file})>
<IMG SRC=${current_file} border=1></A>
<P>
$(basename ${current_file}) (Klicka på bilden för att se den i \
originalstorlek)
</BODY>
</HTML>
EOF
	previous_file=$current_file
    done
}

# make thumbnails and web sized images
mkdir -p $WEBDIR
mkdir -p $THUMBDIR
dirlist=$(find $JPEGDIR -follow -maxdepth 1 -name '*.JPG' -or \
-name '*.jpg' | sort)
for jpegfile in $dirlist; do
    # make a thumbnail
    if echo $jpegfile | grep -q ".JPG$" ; then
	thumbfile=$(basename $jpegfile .JPG)_thumb.jpg
    else
	thumbfile=$(basename $jpegfile .jpg)_thumb.jpg
    fi
    echo "Making a thumbnail of $jpegfile"
    convert -size 120x120 $jpegfile -resize 120x120 +profile '*' \
$THUMBDIR/$thumbfile
    # make a web sized image
    echo "Making a web sized image of $jpegfile"
    convert -size 768x768 $jpegfile -resize 768x768 \
$WEBDIR/$(basename $jpegfile)
done

# make an index file for the thumbnail images
INDEX_FILE=$WEBDIR/index.html
cat <<EOF >$INDEX_FILE
<HTML>
<HEAD>
<LINK REV="made" HREF="mailto:$USER@$(dnsdomainname)">
<TITLE>${TITLE}</TITLE>
</HEAD>
<BODY>
<H2>${TITLE}</H2>
<TABLE>
<TR VALIGN=bottom>
EOF

thumblist=$(find $THUMBDIR -maxdepth 1 -name '*.JPG' -or \
-name '*.jpg' | sort)
linecount=0
for file in $thumblist; do
    base=$(basename $file _thumb.jpg)
    cat <<EOF >>$INDEX_FILE
<TD ALIGN=center><A HREF=${base}.html>
<IMG SRC=$THUMBDIR_NAME/$(basename ${file})></A></TD>
EOF

    if ! ((++linecount%5)) ; then
	cat <<EOF >>$INDEX_FILE
</TR>
<TR VALIGN=bottom>
EOF

    fi
done
cat <<EOF >>$INDEX_FILE
</TR>
</TABLE>
</BODY>
</HTML>
EOF

files=$(find $WEBDIR -maxdepth 1 -name '*.JPG' -or \
-name '*.jpg' | sort)
last_item $files
make_all_html $files
 
Får man slänga upp små C++-program(Binär/Källkod) om man har det? Eller Perl? :) Såklart för Linux.
 
Skurmedel skrev:
Får man slänga upp små C++-program(Binär/Källkod) om man har det? Eller Perl? :) Såklart för Linux.
Jag skrev visserligen shell-skript, men kör på du, det skadar inte med lite annat också. Bara de inte blir allt för långa saker. En poäng med små korta saker är att det är lättare att förstå dem och kanske lära sig ett o annat på kuppen.

Till Per Danielsson vill jag säga; Tack, det där med "cat <<EOF >" var finurligt och gör saker lite enklare, den metoden kände jag inte till och jag kommer helt säkert att få nytta av det.
 
ANNONS
Upp till 6000:- Cashback på Sony-prylar