Valamit nem értek. Persze lehet, hogy csak nem veszek észre valami triviálisat, ha erről lenne szó, írjátok meg! Köszi.
Feladat: ki akartam válogatni a mentéseimből a videókat, amik egy adott dátum után készültek.
Több iteráción keresztül eljutottam oda, hogy azonosítottam azokat a fájl kiterjesztéseket, amik nem képek, nem egyebek, hanem vagy videó, vagy nem ismerem és akár videó is lehet.
Megszámoltam, hány ilyen van (1):
$ find -L /mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 | wc -l
834
OK, gondoltam legyűjtöm ezeket egy helyre, hogy ne kelljen mindig a finddal vacakolni (2):
$ find -L /mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 -print -exec ln -s '{}' . \;
A könyvtárban viszont ennél jóval kevesebb fájl lett:
$ ls -1 | wc -l
348
Na, gondoltam, bizonyára voltak duplikációk, nem tudta ugyanazt a symlinket használni többször azonos nevű fájlokhoz, stb.
Jó, gondoltam, lementem a fájl listát, basename | sort | uniq és meglátjuk, hogy jó eredmény jön-e ki, vagy van olyan, ami valami más miatt maradt le. (3)
$ find -L /mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 -print > filelistln-s.txt
$ wc -l filelistln-s.txt
348 filelistln-s.txt
Izé. Itt elakadtam.
Ha jól látom, a két parancs (1), ami 834-et ad, és (2) meg (3), ami 348-at ad, ugyanazokat a válogatási paramétereket adja a findnak, csak a -print az eltérés.
Nézzük, mit mond a man find:
If no expression is given, the expression -print is used
...
-print True; print the full file name on the standard output, followed by a newline.
Szóval elméletileg a -print megadása az utasítás végén az égvilágon semmit nem változtat, ha nem adom meg, akkor is ugyanúgy végrehajtja.
(a problémámat a két különböző fájl lista összehasonlításával tudom egyébként kezelni, szóval ez nem akadályoz, csak elgondolkoztatott).
Viszont tovább nézve a fájlok különbségét, feltűnt, hogy a 834 darabosban számos olyan fájl van, ami a megadott dátum előtti. A 348-asban nem találtam egyet se (szemmel átfutva).
Nem tudom még, hogy ez-e az egyetlen különbség, de ez megint felvet egy kérdést:
Ha a két esetben a find-nak átadott paraméterlista ugyanaz, akkor miért lehet eltérés az eredményben?
Azt írja a man, hogy operátorok (pl. -o és -a) kapcsolják össze a kifejezés elemeit, és ha hiányzik az operátor, akkor logikai és kapcsolatot feltételez.
Ez alapján a -newerXY elem és kapcsolatban van a többivel, szóval nem értem, hogy találhatott a find olyasmit, ami korábbi.
És máskor meg ügyesen kihagyja ezeket.
- 1287 megtekintés
Hozzászólások
for i in $(find -L * -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15); do ln -s $i; done
$ find -L /mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 -print > filelistln-s.txt
helyette:
$ rm filelistln-s.txt
$ touch filelistln-s.txt
$ find -L /mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 >> filelistln-s.txt
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Próbáld ki, mi történik, ha kiteszed a zárójeleket?
find -L /mnt/nas/backup/Pictures/ \
\( -iname '*.3gp' -o -iname '*.amr' -o -iname '*.m4a' -o -iname '*.mov' -o -iname '*.avi' -o -iname '*.mp4' \) \
-type f -newermt 2013-11-15
- A hozzászóláshoz be kell jelentkezni
Érdekes. Úgy tűnik, így működik. Köszönöm, jó ötlet, tegnap éjjel nem jutott eszembe ebben az irányban keresni a hibát.
gee@hawk:~/Videok_teszt/findtest$ find -L mnt/nas/backup/Pictures/ \( -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 \) -type f -newermt 2013-11-15 -print | wc -l
7
gee@hawk:~/Videok_teszt/findtest$ find -L mnt/nas/backup/Pictures/ \( -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 \) -type f -newermt 2013-11-15 | wc -l
7
Ezek alapján arra gondolok, hogy nem simán balról jobbra dolgozza fel a kifejezés részeit, ahogy én azt a man alapján gondoltam, hanem a boolean AND magasabb precedenciájú mint a boolean OR.
Lássuk, megtalálom-e a manuálban (ez a hátránya az ilyen hosszú man oldalaknak. Az ember rákeres erre-arra, de nem olvas mindent végig)
GNU find ... [evaluates the]
expression from left to right, according to the rules of precedence (see section OPERATORS), until the outcome is known (the left hand side is false for and operations, true for or), at which point find moves on to the next file name
OPERATORS
Listed in order of decreasing precedence:
( expr )
...
expr1 -a expr2
expr1 -o expr2Please note that -a when specified implicitly (for example by two tests appearing without an explicit operator between them) or explicitly has higher precedence than -o. This means that find . -name afile -o -name bfile -print will never print afile.
Egyfelől igen, megvan a rész, amit nem olvastam el éjjel.
És az utolsó példa arra is rávilágít, miért változtatta meg a -print az eredményt.
Ezek szerint ha explicit kiírtam a -print vagy -exec akciót, akkor csak a friss mp4-ekre illeszkedett, ezek nélkül meg a friss mp4-ekre és az összes többi kiterjesztésre dátum ellenőrzés nélkül.
- A hozzászóláshoz be kell jelentkezni
Amúgy a képek dátum szerinti rendezésére ezt is használhatod (ha már egyszer vki megcsinálta):
https://github.com/mb243/exifsort
A videóknál a mediainfo-t érdemes használni a metaadatokhoz, vélhetően pontosabb lesz, mint az egyéb dátumok....
Akár a képes script is átírható videóra :)
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Igazából nem a sorbarendezés volt a lényeg.
Minden* videót ki akartam gyűjteni, ami egy konkrét dátum után készült.
* de igazából óriási pontosság nem kell, ha belekerül pár videó ami korábbi, az nem gond, és az sem, ha néhány nincs benne a listámban.
Az viszont zavar, ha a találatok több, mint fele teljesen rossz (túl korai)
- A hozzászóláshoz be kell jelentkezni
Igen, de ha feltételezzük, hogy digitálisan rögzített felvételekről van szó, akkor a mediainfo paranccsal megkapod a rögzített dátumot (már ha az eszköz helyesen volt beállítva)
üdv: pomm
A 852-es kídlap telepötúsa sikeresen befejezádétt
- A hozzászóláshoz be kell jelentkezni
Idézőjel-idézőjel-idézőjel!
$ find /home/storage/kepek/ -iname *.jpg | wc -l
0
$ find /home/storage/kepek/ -iname "*.jpg" | wc -l
5553
Megoldás:
$ ls
x.jpg
Szóval elméletileg a -print megadása az utasítás végén az égvilágon semmit nem változtat, ha nem adom meg, akkor is ugyanúgy végrehajtja.
A man azt írja, ha nincs semmi "akció" megadva, akkor a -print
fut le (If no expression is given).
Persze ezek nem feltétlen adnak választ a kérdéseidre, viszont érdemes szem előtt tartani.
- A hozzászóláshoz be kell jelentkezni
Igen, az idézőjel okozhatott volna gondot, de újra futtatva nem adott különböző eredményt.
Közben készítettem egy kisebb halmazt tesztelni (a nagyobb halmazon minden futás 2 perc felett volt):
ee@hawk:~/Videok_teszt/findtest$ ls -lA
total 4
drwxr-xr-x 3 gee gee 4096 Oct 22 23:38 mnt/
gee@hawk:~/Videok_teszt/findtest$ find -L mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 | wc -l
36
gee@hawk:~/Videok_teszt/findtest$ find -L mnt/nas/backup/Pictures/ -iname *.3gp -o -iname *.amr -o -iname *.m4a -o -iname *.mov -o -iname *.avi -o -iname *.mp4 -type f -newermt 2013-11-15 -print | wc -l
7
gee@hawk:~/Videok_teszt/findtest$ find -L mnt/nas/backup/Pictures/ -type f -newermt 2013-11-15 -print | wc -l17
gee@hawk:~/Videok_teszt/findtest$ find -L mnt/nas/backup/Pictures/ -type f -newermt 2013-11-15 | wc -l
17
Ahogy az első két find utasításból látható, az üres könyvtáron is ugyanaz a jelenség adódik.
Viszont érdekes módon, ha nem próbálok névre szűrni, akkor azonos az eredmény.
- A hozzászóláshoz be kell jelentkezni
Úgy már próbáltad, ahogy NevemTeve javasolta?
Egy hevenyészett teszttel én is hasonló eredményt produkálok:
$ mkdir -p a/a{b,c,d,e}
$ touch a/a{b,c,d,e}/f0{1,2,3,4,5}.avi
$ touch a/a{b,c,d,e}/f0{1,2,3,4,5}.jpg
$ touch a/a{b,c,d,e}/f0{1,2,3,4,5}.png
find
-parancsok:
$ find a/ -print -iname "*.png" -o -iname "*.jpg" -type f | wc -l
65
$ find a/ -iname "*.png" -o -iname "*.jpg" -type f -print | wc -l
20
A két lekérdezésben annyi a különbség, hogy a -print
az elején vagy a végén van-e. A trükk az, hogy a -print
nem utasítás, hogy mit csináljon, hanem "teszt" ("expression", "primaries"), ami mindig igazat ad vissza.
Az első lényegében ("print" és "png") vagy ("jpg" és "file")
módon értelmezendő.
A második ("png") vagy ("jpg" és "file" és "print")
(pl. egy foo.png
nevű könyvtárat(!) is listáz).
Bár bevallom, az alábbi eredmények nemigen tiszták számomra:
$ find a/ \( -iname "*.jpg" -o -iname "*.png" \) -type f -print | wc -l
40
$ find a/ -print \( -iname "*.jpg" -o -iname "*.png" \) -type f | wc -l
65
- A hozzászóláshoz be kell jelentkezni
Igen, próbálgattam, ezért hosszan tartott a válasz megírása, de a végére tiszta lett.
Mondjuk a te utolsó két utasításod különbségét még mindig nem értem :-)
- A hozzászóláshoz be kell jelentkezni
Hát, ha a -print van az elején, akkor azzal kezdi, hogy megcsinálja a kiírást, utána foglalkozik a többi feltétellel.
- A hozzászóláshoz be kell jelentkezni
OK, szóval kilistáz mindent, amit megvizsgált.
- A hozzászóláshoz be kell jelentkezni
Hm. Lehet, hogy van benne valami:
$ find a/ -print -o -iname "*.xyz" | wc -l
65
$ find a/ -print -iname "*.xyz" | wc -l
65
És ha a végén van?
$ find a/ -iname "*.xyz" -o -print | wc -l
65
$ find a/ -iname "*.xyz" -print | wc -l
0
Nemigen értem a logikát, ami lenne az egész mögött. Első közelítésre azt mondanám, hogy az és művelet nem kommutatív. Vagy esetleg az a mondás, hogy ha az -iname
hamist ad, akkor a -print
értékétől függetlenül úgyis hamis a végeredmény?
- A hozzászóláshoz be kell jelentkezni
A logikai műveleteknél számít a sorrend (ha nem, az tervezési hiba):
true AND valami => valami
false AND valami => false ('valami'-t nem számoljuk ki / végezzük el)
true OR valami => true ('valami'-t nem számoljuk ki / végezzük el)
false OR valami => valami
ha van/lenne IMP (implies), akkor:
true IMP valami => valami
false IMP valami => true ('valami'-t nem számoljuk ki / végezzük el)
- A hozzászóláshoz be kell jelentkezni
Akkor ez miért van így (true AND false
)?
$ find a/ -print -iname "*.xyz" | wc -l
65
Vagy a -print
-re nem úgy kell gondolni, mint egy true
értékre, hanem inkább úgy, mint egy függvényre, ami mindig true
-t ad vissza és (amikor a kiértékelésére kerül a sor) mellékesen kiír egy rakat dolgot?
Talán az utóbbi verziót támasztja alá:
$ find a/ -print | wc -l
65
$ find a/ -print -print | wc -l
130
- A hozzászóláshoz be kell jelentkezni
> find a/ -print -iname "*.xyz"
Jaja, a 'végső eredmény' ugyan false, de attól még a print megtörténik a legelején.
- A hozzászóláshoz be kell jelentkezni