Sida 1 av 1
find -exec (alternativt find -print0 | xargs -0…)
Postat: 28 aug 2008, 17:04
av Johnny Rosenberg
Jag försöker göra en sak här, men då jag efter ett stort antal försök ännu inte lyckas känns det som att någon helt enkelt gärna får berätta för mig vilken klant jag är som inte klarar av detta enkla:
Jag har just installerat imagemagick (tror jag det heter…) och tänkte enbart, i alla fall för tillfället, använda dess convert-kommando. Kommandot har jag fått att fungera alldeles utmärkt, jätteenkelt. Vad jag vill göra är att konvertera jpg-filer till jpg-filer, med den skillnaden att de nya filerna ska ta mindre plats. Bildkvaliteten spelar en väldigt liten roll då det bara rör sig om inskannade (eller på senare tid fotograferade, eftersom det går snabbare och att skannern jag har saknar drivrutin för Linux) papper mestadels innehållande text. Jag har experimenterat lite och fann att texten blir mer än läsbar redan vid en kvalitetssiffra på 40 av 100, så följande kommando gör jobbet perfekt åt mig:
Detta funkar precis som jag vill ha det, den gamla filen skrivs över utan att knysta en massa strunt om huruvida jag verkligen vill skriva över eller inte, exakt som jag vill ha det. Så långt allt väl.
Nu vill jag utföra detta kommando för alla jpg-filer i en mapp och alla dess undermappar med en enda rad och tänkte då använda find, men strular bara till det. Jag misstänker att jag sätter citattecken och liknande på fel ställen helt enkelt, men hur jag än kombinerar skiten så får jag alltid något felmeddelande.
Jag hade tänkt mig en av två möjligheter till konstruktion:
1.
Kod: Markera allt
find . -name "*.jpg" -size 300k print0 | xargs -0 <själva kommandot, och det är nog här det skiter sig>
2.
Kod: Markera allt
find . -name "*.jpg" -size 300k -exec <själva kommandot, men jag kan inte komma på hur man slänger in samma filnamn på två ställen, för {} kan man tydligen bara använda en gång i en sådan sats>
Sen är jag osäker på hur -size funkar också. Kommer den att hitta bara de som är större eller bara de som är mindre än den storlek man angett? Men jag kan tänka mig att strunta i -size också. Det var mest för att spara lite tid genom att strunta i bilder som ändå inte behöver komprimeras ytterligare.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 28 aug 2008, 17:50
av Konservburk
Johnny Rosenberg skrev:följande kommando gör jobbet perfekt åt mig:
Detta funkar precis som jag vill ha det, den gamla filen skrivs över utan att knysta en massa strunt om huruvida jag verkligen vill skriva över eller inte, exakt som jag vill ha det. Så långt allt väl.
Nu vill jag utföra detta kommando för alla jpg-filer i en mapp och alla dess undermappar med en enda rad och tänkte då använda find, men strular bara till det. Jag misstänker att jag sätter citattecken och liknande på fel ställen helt enkelt, men hur jag än kombinerar skiten så får jag alltid något felmeddelande.
Jag hade tänkt mig en av två möjligheter till konstruktion:
1.
Kod: Markera allt
find . -name "*.jpg" -size 300k print0 | xargs -0 <själva kommandot, och det är nog här det skiter sig>
2.
Kod: Markera allt
find . -name "*.jpg" -size 300k -exec <själva kommandot, men jag kan inte komma på hur man slänger in samma filnamn på två ställen, för {} kan man tydligen bara använda en gång i en sådan sats>
Kod: Markera allt
find . -iregex '.*\.jpe?g' -size +300k -print0 | xargs -0 -i convert {} -quality 40 {}
Kod: Markera allt
find . -iregex '.*\.jpe?g' -size +300k -exec convert {} -quality 40 {} \;
Men båda dessa varianter är ganska ineffektiva eftersom de kör
convert 1 gång per fil. Tricket är att använda
mogrify istället:
Kod: Markera allt
find . -iregex '.*\.jpe?g' -size +300k -print0 | xargs -0 mogrify -quality 40
Kod: Markera allt
find . -iregex '.*\.jpe?g' -size +300k -exec mogrify -quality 40 {} +
Johnny Rosenberg skrev:Sen är jag osäker på hur -size funkar också. Kommer den att hitta bara de som är större eller bara de som är mindre än den storlek man angett? Men jag kan tänka mig att strunta i -size också. Det var mest för att spara lite tid genom att strunta i bilder som ändå inte behöver komprimeras ytterligare.
Den hittar filer som är 300k när du använder
-size 300k. För att hitta filer som är större än 300k använder du istället
-size +300k.
Sen har vi skillnaden mellan
-name "*.jpg" och
-iregex '.*\.jpe?g' . Den första hittar bara filer som slutar på .jpg, medan den andra även hittar de som slutar på .jpeg, .JPG, .JpEg, osv.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 28 aug 2008, 18:18
av Johnny Rosenberg
Jisses! Det finns ju hur mycket som helst att veta om detta! Var har du lärt dig allt? Skicka mig dit också…
Ska ta mig tid att bearbeta ditt svar senare, min fru vill att vi ska handla mat… och det kan ju också vara bra att ha, speciellt när man är hungrig…
Återkommer och visar ytterligare prov på min okunnighet.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 28 aug 2008, 21:44
av Johnny Rosenberg
Så där, nu har jag hunnit studera de olika alternativen lite samt klockat dem… (visst är det kul med tidtagning…

)
Fyra förslag alltså, med varning för att de två första är ineffektiva:
Kod: Markera allt
1: find . -iregex '.*\.jpe?g' -size +300k -exec convert {} -quality 40 {} \;
2: find . -iregex '.*\.jpe?g' -size +300k -print0 | xargs -0 -i convert {} -quality 40 {}
3: find . -iregex '.*\.jpe?g' -size +300k -print0 | xargs -0 mogrify -quality 40
4: find . -iregex '.*\.jpe?g' -size +300k -exec mogrify -quality 40 {} +
Jag skapade för experimentet en mapp med kopior av 16 bilder av rätt format, alla ca 1,1-1,3 MiB. Kanske för få filer för att tydligt göra skillnad på de olika metoderna, men det som tar särklassigt längst tid verkar ju vara själva konverteringen, så det blev ungefär samma tid på allihop.
1: 17,6 s
2: 17,6 s
3: 17,2 s
4: 17,4 s
Allt i lite runda tal, så där. Det verkar återigen vara xargs-alternativet som är snabbast, men som sagt så är inte skillnaden så stor. Sen har ju 1 och 2 den nackdelen att convert kräver ett argument mer än mogrify.
En kanonlösning igen, man tackar!
Det är lustigt, själv sitter man och sliter sitt hår och det blir bara fel hela tiden, sedan rapar du ur dig fyra lösningar i förbifarten och det bara fungerar…

Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 29 aug 2008, 00:50
av Konservburk
Eftersom läsa in och konvertera bilder är relativt långsamt så blir det ju inte så stor skillnad, och 16 bilder är dessutom på tok för lite för att det ska vara märkbart. Med tusentals bilder kan du säkert spara in många sekunder om du väljer rätt metod.
Dessutom är convert tänkt att användas med olika in- och ut-filer, medan mogrify är precis samma program, fast med tanken att man ska skriva över de ändrade bilderna istället.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 29 aug 2008, 12:21
av Johnny Rosenberg
Konservburk skrev:Eftersom läsa in och konvertera bilder är relativt långsamt så blir det ju inte så stor skillnad, och 16 bilder är dessutom på tok för lite för att det ska vara märkbart. Med tusentals bilder kan du säkert spara in många sekunder om du väljer rätt metod.
Dessutom är convert tänkt att användas med olika in- och ut-filer, medan mogrify är precis samma program, fast med tanken att man ska skriva över de ändrade bilderna istället.
Precis.
verkar vara exakt samma sak som
I båda fallen skrivs originalfilen brutalt över, precis i min smak! Har man ingen backup får man skylla sig själv, så jag vill inte ha något trams om ”är du säker” och så vidare.
Jag reagerade ju aldrig, när jag läste dokumentation på nätet om ImageMagick, på Mogrify, för det är ett nytt ord för mig vars betydelse jag inte känner till. Convert vet man ju vad det betyder, så det hittade jag ju enkelt. Ser man något man inte vet vad det betyder är det ju lätt att tänka att ”det är nog inget som gäller mig”… Det står inte med i den ordlista jag brukar kolla i heller.
I mitt test verkar det ju som att själva konverteringen tar ca 1 sekund per bild, så om man konverterar tusentals bilder så spelar ändå några sekunder inte så stor roll, för när datorn väl är klar håller man ändå på med något annat. Det vanliga är nog att man tittar till den efter väldigt lång tid och konstaterar att den förmodligen var klar för längesen…
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 29 aug 2008, 14:28
av Konservburk
Det handlar såklart inte om någon stor procentell skillnad eftersom själva bildbehandlingen tar så pass mycket tid. Men det betyder ju inte att ska avstå från att välja det "bättre" alternativet.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 10:29
av TobbeT
Hej,
Hur gör man om man vill behålla originalfilen (fotot) och placera de konverterade bilderna till en ny underkatalog som exempelvis kan heta 1280x960.
Exempel:
Under mappen Foto/Tobbe/2008/2008-09-01/finns 100 foton i formatet 3072 x (kommer inte ihåg siffran här) men filerna brukar var 2-4MB stora. Dessa vill jag konvertera om till 1280x960 med automatik (script), och det scriptet ska även skapa katalogen Foto/Tobbe/2008/2008-09-01/1280x960, samt att filnamnet ska vara detsamma som originalet.
Jag har image-convert installerat men jag måste hela tiden klippa ut de konverterade bilderna, skapa ny katalog och klistra in där, lite tidskrävande tycker jag.
//Tobbe
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 11:20
av Konservburk
TobbeT skrev:Hur gör man om man vill behålla originalfilen (fotot) och placera de konverterade bilderna till en ny underkatalog som exempelvis kan heta 1280x960.
find -exec / find -print0 | xargs -0 behöver du bara använda om du har en massa underkataloger med bilder som du också vill ändra storlek på (eller om du har väldigt många bilder så att argumentlistan blir för lång). Annars räcker det att göra ungerfär så här:
Kod: Markera allt
cd Foto/Tobbe/2008/2008-09-01/
mkdir -p 1280x960 && mogrify -path 1280x960 -scale "1280x960>" *.jpg
Vill du använda det här flera gånger så kan du göra en skalfunktion som du sparar i ~/.bashrc:
Kod: Markera allt
scale_jpg() { mkdir -p "$1" && mogrify -path "$1" -scale "$1>" *.jpg; }
Sedan är det bara att gå till rätt katalog och köra den egna funktionen:
Kod: Markera allt
cd Foto/Tobbe/2008/2008-09-01/
scale_jpg 1280x960
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 11:34
av TobbeT
Så om jag står här --> Foto/Tobbe och där under har jag katalogerna 2005, 2006, 2007 & 2008 (som i sin tur har mappar i datumordning) och vill konvertera alla bilder samt skapa katalogen 1280x960 under respektive datum, hur blir det då?
Exempel:
Foto/Tobbe (här vill jag stå jag när skriptet körs, och det ska söka i alla undermappar, konvertera, skapa mappen 1280x960 med samma filnamn som originalet.)
Foto/Tobbe/2005\datumordning
Foto/Tobbe/2006\ " - "
Foto/Tobbe/2007\ " - "
Foto/Tobbe/2008\ " - "
osv
Foto/Tobbe/2005/2005-05-05/1280x960 <--- den här mappen ska scriptet skapa
Så ser strukturen ut för varje år.
//Tobbe
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 13:54
av Konservburk
TobbeT skrev:Så om jag står här --> Foto/Tobbe och där under har jag katalogerna 2005, 2006, 2007 & 2008 (som i sin tur har mappar i datumordning) och vill konvertera alla bilder samt skapa katalogen 1280x960 under respektive datum, hur blir det då?
Du kan t.ex. stoppa in det vi hade innan i en slinga:
Kod: Markera allt
scale_jpg() {
find ! -name "$1" -type d -print0 |
while read -d '' DIR
do cd "$DIR" && mkdir -p "$1" && mogrify -path "$1" -scale "$1>" *.jpg
done
}
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 14:16
av Konservburk
Kom på att det kanske är bra att lista en
find -exec variant också, eftersom tråden handlar om just det:
Kod: Markera allt
find -iregex '.*\.jpe?g' -type f -execdir mkdir -p 1280x960 \; -execdir mogrify -path 1280x960 -scale 1280x960\> {} \;
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 15:29
av TobbeT
Tusen tack,
Ska genast testa detta när jag kommer hem. (Bara jag gör rätt)
//Tobbe
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 18:28
av Johnny Rosenberg
TobbeT skrev:Tusen tack,
Ska genast testa detta när jag kommer hem. (Bara jag gör rätt)
//Tobbe
Nog för att du säkert kan lita på de förslag du fått, men ta backup först.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 20:13
av TobbeT
Men det är ju strålande. Så mycket enklare, snabbare och framför allt, man slipper skapa en massa kataloger och kippa ut och klistra in. Nu skulle man kanske önska sig att man fick upp ett litet fönster som säger att "Tobbe, konverteringen är klar". Men det är inget måste.
Tusen tack konvervburk, jag har sagt det förut, och jag säger det igen Du är en klippa ! ! !
//Tobbe
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 20:44
av Konservburk
TobbeT skrev:Nu skulle man kanske önska sig att man fick upp ett litet fönster som säger att "Tobbe, konverteringen är klar".
Jag tror du kan använda
Xdialog om du vill få ett meddelande i ett nytt fönster, eller bara vanliga
dialog för att få det direkt i terminalen.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 20:58
av TobbeT
Kod: Markera allt
find -iregex '.*\.jpe?g' -type f -execdir mkdir -p 1280x960 \; -execdir mogrify -path 1280x960 -scale 1280x960\> {} \;
Om jag bestämmer mig för att använda den här kodsträngen, vart lägger jag Xdialog --msgbox
Konverteringen är klar! 5 20?
(
Kanske bäst att skapa en ny tråd snart. Känns som jag har kommit ifrån den egenliga topicen)
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 01 sep 2008, 21:36
av Konservburk
TobbeT skrev:Om jag bestämmer mig för att använda den här kodsträngen, vart lägger jag Xdialog --msgbox Konverteringen är klar! 5 20?
Först bör du testa så att syntaxen för
Xdialog är rätt. Jag har inte det programmet installerat, så jag kan inte testa själv. Du vill åtminstone ha fnuttar runt själva textsträngen och ändra
5 20 till en vettigare storlek (Jag bara högg något ur luften så att säga). Testa dig helt enkelt fram till ett kommando som du är nöjd med.
Sen, oavsett vilken variant du väljer, så finns det tre olika sätt beroende på vad du vill göra:
Xdialog körs när
kommando kört klart.
Xdialog körs när
kommando kört klart, men bara om det lyckades.
Xdialog körs när
kommando kört klart, men bara om det misslyckades.
TobbeT skrev:(Kanske bäst att skapa en ny tråd snart. Känns som jag har kommit ifrån den egenliga topicen)
Jag kan dela tråden om du tänker fortsätta på det här sidospåret.
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 02 sep 2008, 08:43
av TobbeT
Vi kan nog anse att den här tråden är klar. Får jag inte till det med xdialog så är inte det hela världen. Tack än en gång.
//Tobbe
Re: find -exec (alternativt find -print0 | xargs -0…)
Postat: 02 sep 2008, 18:48
av Johnny Rosenberg
TobbeT skrev:Vi kan nog anse att den här tråden är klar. Får jag inte till det med xdialog så är inte det hela världen. Tack än en gång.
//Tobbe
Antar att jag kan yttra mig eftersom det var jag som ställde frågan från början, och för min del så hade jag redan fått mitt svar innan diskussionen om Xdialog påbörjades, men jag fann att Xdialog var något jag själv kunde använda också, och som jag delvis saknat i mina backup-skript, något som talar om för mig att skriptet är klart, förutom att terminalfönstret stängs då, om jag kör programmet via en startare och väljer att köra i terminal.
Installerade både dialog och Xdialog och fann att Xdialog var grejen, i mitt specifika fall. Användbar information som jag kanske inte hade läst om den inte hamnat i min tråd… så tack för denna bonus!
Upptäckte också att det ska vara Xdialog, inte xdialog, när man kör, men xdialog när man installerar det… Lite udda kanske man kan tycka. Och givetvis också att man, som vanligt måste innesluta sina små meddelanden i exempelvis "dubbelfnuttar" om man vill att meddelandet ska vara mer än bara ett enda ord, men det är väl självklarheter, i och för sig.