find -exec (alternativt find -print0 | xargs -0…)

Här diskuterar vi skal, kommandon och klassiska linuxverktyg.
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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:

Kod: Markera allt

convert minfil.jpg -quality 40 minfil.jpg
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.
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg av Konservburk »

Johnny Rosenberg skrev:följande kommando gör jobbet perfekt åt mig:

Kod: Markera allt

convert minfil.jpg -quality 40 minfil.jpg
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.
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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å… ;D

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.
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg av Johnny Rosenberg »

Så där, nu har jag hunnit studera de olika alternativen lite samt klockat dem… (visst är det kul med tidtagning… :D)

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… :D
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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.
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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.

Kod: Markera allt

mogrify a [option]
verkar vara exakt samma sak som

Kod: Markera allt

convert a [option] a
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…
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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.
Användarvisningsbild
TobbeT
Inlägg: 670
Blev medlem: 20 feb 2007, 11:45
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Eskilstuna

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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
Användarvisningsbild
TobbeT
Inlägg: 670
Blev medlem: 20 feb 2007, 11:45
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Eskilstuna

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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
}
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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\> {} \;
Användarvisningsbild
TobbeT
Inlägg: 670
Blev medlem: 20 feb 2007, 11:45
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Eskilstuna

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg av TobbeT »

Tusen tack,

Ska genast testa detta när jag kommer hem. (Bara jag gör rätt) :)

//Tobbe
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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.
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Användarvisningsbild
TobbeT
Inlägg: 670
Blev medlem: 20 feb 2007, 11:45
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Eskilstuna

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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
GGS-Data Elite, 5200+ 4GB RAM Ubuntu 11.04 64-bitars, 2x500GB HD
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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.

Kod: Markera allt

Xdialog --msgbox hejsan 5 20

Kod: Markera allt

dialog --msgbox hejsan 5 20
Användarvisningsbild
TobbeT
Inlägg: 670
Blev medlem: 20 feb 2007, 11:45
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Eskilstuna

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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)
GGS-Data Elite, 5200+ 4GB RAM Ubuntu 11.04 64-bitars, 2x500GB HD
Användarvisningsbild
Konservburk
Inlägg: 5919
Blev medlem: 07 apr 2007, 22:28

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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:

Kod: Markera allt

kommando ; Xdialog
Xdialog körs när kommando kört klart.

Kod: Markera allt

kommando && Xdialog
Xdialog körs när kommando kört klart, men bara om det lyckades.

Kod: Markera allt

kommando || Xdialog
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.
Användarvisningsbild
TobbeT
Inlägg: 670
Blev medlem: 20 feb 2007, 11:45
OS: Ubuntu
Utgåva: 24.04 Noble Numbat LTS
Ort: Eskilstuna

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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
GGS-Data Elite, 5200+ 4GB RAM Ubuntu 11.04 64-bitars, 2x500GB HD
Användarvisningsbild
Johnny Rosenberg
Inlägg: 1256
Blev medlem: 23 jun 2007, 16:18
OS: Ubuntu
Utgåva: 22.10 Kinetic Kudu
Kontakt:

Re: find -exec (alternativt find -print0 | xargs -0…)

Inlägg 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! :D

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.
Vänliga hälsningar

Johnny Rosenberg
ジョニー・ローゼンバーグ

IEEE 1541 - binära prefix
ISO 8601 - datum och tid
Skriv svar

Återgå till "Terminalforum"