fájlok átnevezése

Képeket dolgoznék fel szkripttel, és most dilemma az mv parancs. Mi van ha már létezik olyan nevű fájl azon a helyen ahová az mv parancs tenné az aktuális feldolgozandó fájlt? mv --backup=numbered file to/ 
Ezzel csak az gondom hogy a kiterjesztés után teszi a növekvő számokat az azonos fájlok esetén. pic001.jpg > pic001.jpg.~1~  pic001.jpg.~2~  stb. Így még a képnéző sem látja.

Én inkább ilyen megoldást keresek: pic001.jpg > pic001_1.jpg pic001_2.jpg stb. Hogyan oldhatom meg ezt? 

Hozzászólások

Szerkesztve: 2023. 02. 14., k – 10:56

Kb ezek a lepesek:

 - 1. megnezed hogy letezik-e a celteruleten

 - 2. ha igen, akkor kitalalsz vmi uj nevet neki a sajat logikad szerint, es goto 1,

- 3. az ` mv -n` kapcsoloval atmozgatod, ez garantalja az atomi atmozgatast. ha nem sikerul akkor ujabb nevet talalsz ki neki majd goto 1.

- 4. problem solved, profit!

Tovabbi olvasnivalonak, es ugy altalaban az atomi file muveletekkel kapcsolatos dolgok megismeresehez ajanlom eztet itten

Es ez az "uj nevet talalsz ki" dolog az valami ilyesmi lehet: base=${picturefile%\.jpg}; es akkor az uj nev ${base}_${n}.jpg, ahol n=$((n+1)) modon noveled az erteket ha a 2. ill 3. lepes azt mondja hogy mar letezik a file. 

miután lement az mv, csinálj rename-et:

rename 's/((?:\..+)?)\.~(\d+)~$/_$2$1/' *.~*~

ezzel vigyázz, csak akkor megy ha nincs többszörös kiterjesztés, archive.tar.gz.~5~ -> archive.tar_5.gz lesz és megint nem lesz jó.

Link (itt van több példa is, pl sed használatával).

szerintem csak a mv paranccsal nem fogod tudni megoldani, viszont egy bash szkriptböl egy ciklussal megoldható.

a basename visszaadja a fájl nevét utvonalak nélkül, a ${filename##*.} a végzödést a ${filename%.*} a fájl nevét végzödés nélkül.

if [ -f "$filename" ] pedig visszaadja hogy a fájl létezik-e, ha igen, össze tudod rakni az új fájlnevet "_$num"-al 

Szerk: itt egy kódrészlet volt, de annyira vérzett 1000 sebböl, hogy inkáb kivettem

bash basename-mel kinyered a kiterjesztés előtti részt majd ahhoz ragasztgatod amit akarsz?

Megcsinálod ezt az átnevezést, majd utána az egész directoryra lefuttatsz egy jól paraméterezett mmv-t. A mintádat nézve: mmv '*.jpg~*~' '#1#2.jpg' nagyjából azt hozná ki, amit szeretnél.

Szerkesztve: 2023. 02. 14., k – 15:41

Ahogy én csinálnám: először a meglévő képeket átnevezném egy for ciklussal, majd mv-vel mozgatnám a fájlokat:

for whatever in /destination/blah-blah/*.jpg
do
  mv "$whatever" "$whatever _0"
done
mv /source/path/*.jpg /destination/blah-blah

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”

Nem tudni mi a pontos cél a projekttel, milyen, milyen nyelv a cél, ezért ez egy kicsit "out of the box" megoldási javaslat lesz, feltételezve, hogy Linux alatt szeretnéd ezt megvalósítani (hogy menne-e windows-al azt nem tudom megerősíteni).

A forrás (átalakítandó) képeket ott hagyni ahol vannak és a feldolgozott képeket lehetne tenni új mappába.

Az imagemagick csomag telepítése után (convert parancsot kell használni asszem)  elég jól lehet a képekkel dolgozni (méretezés, forgatás stb.) Maga a program támogatja módosított kép mentését más néven és/vagy másik könyvtárba.

Ezt egyszerűen be lehet tolni akár egy bash scriptbe, vagy bármilyen trendi nyelv (Python, Go,  etc. ) alá és csak futtatni kell.

Remélem a fenti ötlet ad valami segítséget.

Tudom mindenki utája amikor valaki nem konkrétan a feltett kérdésre válaszol, hanem a kérdést magát kritizálja, de szerintem hibás a koncepció.

Ha egyszerre több képet dolgozol fel, akkor azok a képek között valószínűleg lesz valami kötődés, nevezzük a kötődést galériának.

Ha névütközésre számítasz, akkor az valószínűleg két eltérő galéria ütközése lesz.

Ha egyesével vizsgálod, hogy van-e olyan, akkor simán össze fogsz fésülni két eltérő galériát, például két év ugyanazon a hónapján és napján készült kirándulás képeit.

Ezért én azt javaslom, hogy mielőtt lemegy a (például a convert parancs), nézze meg a script, hogy az adott helyen az összes input file oda tud-e majd kerülni ütközés nélkül. Ha nem, akkor találjon neki egy prefixet, és azzal lássa el a kimeneti fileokat, így egyrészt megelőzi az ütközést, másrészt a név sorrendet követve egyben maradnak az adott galériához kapcsolódó képek, nem fésülődnek össze.

Lehet hogy nincs igazam, ez esetben bocsánat. Nem kioktatni, vagy beléd kötni akarok, csupán egy lépéssel hátrébb lépve egy más nézőpontból nézve, egy lehet, hogy a te céljaidat jobban szolgáló válasz jutott az eszembe. Ha nincs szó galéria ütközésekről, akkor amit írtam, az értelemszerűen semmis.

OK. Köszönöm a hozzászólásokat, de mindig gondban vagyok egy-egy kérdés feltevéssel. Mi az ami elég, mi az ami már túl sok. Mindenkinek más a vérmérséklete, tűrése  egy-egy poszt hosszán, megfogalmazásán.
A lényeg, hogy én aki nem győzöm hangsúlyozni - úton-útfélen - nem vagyok. programozó, írtam mások szerint egy gány bash szkriptet, amely megfigyeli hogy az adott kép tartalmaz-e GPS adatokat. Ha nem, akkor az adott képet átmozgatja a noGPS mappába. Az itteni duplikátumok kérdését megoldottam egy atombombával, mert az exiftoolt használom erre a célra. Viszont ha tartalmaz GPS adatokat, akkor az OSM API-tól lekérdezem a település nevet, létrehozom, és beleszórom a képet a település mappába. Itt egyelőre nem jöttem rá hogy miként oldhatnám meg a már említett esetleges duplikátum problémát. Mindenki elrettentésére itt az egész tákolmány.

#!/bin/bash

noGPSdir="noGPS"

if [ ! -d "${noGPSdir}" ]; then
    mkdir "${noGPSdir}"
fi

rename JPG jpg *.JPG 2>/dev/null
chmod 644 *.jpg
for files in *.jpg ; do 
    lat="$(exiftool -n -p '$GPSlatitude' "${files}" 2>/dev/null)"
    lon="$(exiftool -n -p '$GPSlongitude' "${files}" 2>/dev/null)"
    if test -n "${lat}" -a -n "${lon}"; then
        cityName="$(curl -s "https://nominatim.openstreetmap.org/reverse?format=json&lat=${lat}&lon=${lon}" | jq -r '.address.town, .address.village, .address.city' | grep -v "null" | head -n1)" 
        if [ ! -d "${cityName}" ]; then
            mkdir "${cityName}"
        fi
        mv --backup=numbered "${files}" "${cityName}" # amíg nem jut eszembe jobb.
    else # noGPS
        exiftool -ext jpg -d 'PIC_%Y%m%d_%H%M%S%%-c.%%le' '-filename<./noGPS/${datetimeoriginal}' . # Figyelem itt a noGPS mappa nem rakható változóba!
    fi
done

Itt annyit lehetne okosítani, hogy vagy a fájl nevéhez vagy város nevéhez hozzáfűzni a kép létrehozásának dátumát. Mondjuk év és hónap.

Pl.

Könyvtár esetén:  város-YYYYMM

vagy

fájl esetén: fájlnév-YYYYMM.jpg

Ez mindig az adathalmaztól függ mi a jó választás. Lehet, hogy indokolt lenne a napot is beletenni a fájlnévbe, de lehet elég lenne csak az évszám.

Ami ritkán, de szintén ütközhet (Mondjuk mobillal lőtt fotósorozat esetén még a másodperc tört része is azonos lesz...). Erőforrásban többet eszik egy mondjuk md5sum a fájlra, és azt berakni a fájlnévbe, viszont nagyságrendekkel kisebb az esélye az ütközésnek.

Igen millió lehetőség van, ebből leírásra került egy viszonylag egyszerű lehetőség.

Mivel nem tudjuk pontosan milyen jellegűek a képek (profi fotózás, hobbi fotózás), így megoldás kiválasztása a kérdezőre marad.

Ja, ért már meglepetés az md5 használatával,  ezért inkább sha256-ot lehetne használni,  de ez is a kérdezőn múlik igazából. 🙂

Ez később jön. Ha már ez mind megvan, ráeresztek egy újabb exiftoolt.

exiftool -r -ext jpg -progress -d '%Y/%Y-%m/PIC_%Y%m%d_%H%M%S%%-c.%%le' '-filename<%-1:D/${make}_${model}/${datetimeoriginal}' .

Valahogy így: Budapest/PIC_20190323_145832.jpg > Budapest/FUJIFILM FinePix S4800/2019/2019-03/PIC_20190323_145832.jpg - bár ez pont nem igaz, mert ez a gép nem is kezeli a GPS adatokat, de a példa jó.

A -r alkönyvtárak.
-ext jpg - mivel dolgozzon.
-progress elhagyható, ez csak a folyamatábra hogy hol tart.
A -d ' ' - ben csak a dátummal kapcsolatos dolgok lehetnek, és itt van szabályozva a fájl neve. Minden itt megadott szöveg PIC hozzáadódik a fájlnévhez.
A %%c a duplikátumok miatt plusz számot tesz bele.
A %%le a kisbetűs kiterjesztés.
A -filename %-1:D csak oda hoz létre új mappát, ahol éppen a fájlok léteznek. Ennek nagyon örültem.

Van már szkriptem a pasteGPS-re is. Bár ezt természeténél fogva nem lehet teljesen automatizálni. Ha a kép nem rendelkezik GPS adatokkal, de tudom hol készült, megkeresem a Google térképen, és az ottani teszem azt

47°30'31.6"N 19°02'45.2"E adatot feldolgozva a szkript be is teszi a képbe. Itt a kérdés: Ezt a GPS adatot hogy tudom $2-ként megadni? pasteGPS pic01.jpg 47°30'31.6"N 19°02'45.2"E - Itt a sok idézőjel meghülyíti a basht.

Most bonyolultabb, mert pasteGPS pic01.jpg, majd kéri a GPS adatokat.

Mielőtt megkérdezitek miért nem ezt dolgozom fel? 47.508768, 19.045877 - adódik a kérdés hogy a hosszúsági és szélességi ref értékeket ebből hogy tudom meg? Ami a példánál maradva N és E.

$ exiftool  -n   -gpslatitude -gpslatituderef  IMG_20221212_163126.jpg
GPS Latitude                    : xx.2597179722222
GPS Latitude Ref                : N

Amúgy meg: https://appdb.winehq.org/objectManager.php?sClass=application&iId=10332

Félreérted. A kép nem  tartalmaz GPS adatot. Ergo nem is tudom lekérdezni az exiftool-lal. Én rakom majd bele utólag. Hogyan? Megnézem a képet. Ha tudom hol készült, megkeresem a helyét a térképen, s így megtudom a koordinátákat. De ebből az értékből: xx.2597179722222 nem tudom meg a latRef értéket. ... Áááá, most hogy tovább gondolom amit Nyizsa mondott, ha ez az xx.2597179722222 szám pozitív, akkor N mindig észak!!! Hurrá.
Eszembe nem jutott volna. Le is tesztelem.

exiftool -n -GPSLatitude="${lat}" -GPSLatitudeRef="${latRef}" -GPSLongitude="${lon}" -GPSLongitudeRef="${lonRef}" -overwrite_original "${1}"

Nincs ezzel semmi baj.

Persze lehetne rajta csinosítani, de az már csak cicoma.

Programozó én se vagyok, de mint üzemeltetőnek, azért néha kell írni kisebb-nagyobb dolgokat mindenféle scriptnyelven, és nem árt megtanulni pár alap dolgot.

Még tanulom :)

Egyetértek. Sose bírtam ezt a valaki fejlesztő, programozó szöveget. Azok is épp úgy megtanulták anno az alapokat, ők se születtek bele a szakmába. Az esélye a fejlődésre épp úgy meg van mindenkinek, aki hajlandó foglalkozni ilyennel.

A kódjában nem látok semmi hibát. Ha mégis bele kéne kicsit kötni, az a Bash-hoz való ragaszkodás. Nincs benne konkrét bashizmus, bőven jó lenne a #!/bin/sh fejléc is, akkor minden POSIX kompatibilis shellben futni fog, nem hozza be konkrétan a Bash-t függőségnek.

Windows 95/98: 32 bit extension and a graphical shell for a 16 bit patch to an 8 bit operating system originally coded for a 4 bit microprocessor, written by a 2 bit company that can't stand 1 bit of competition.”