A napok adott időszakában létrehozott állományok megtalálása és törlése

Fórumok

Sziasztok!

Próbálom a biztonsági kamera felvételei közül a napok adott időszakában (00:00 - 06:00) létrehozott állományokat törölni.
Ennyit eszkábáltam eddig össze:

find ./ -type f -ls | while read file; do tor=$( echo $file | awk -F ' ' {print $10}' | awk -F ':' {print $1}' ) echo $tor ; if [[ "$tor" -lt "6" ]] ; then echo $tor ; fi ; done

Mi lenne a helyes megoldás?

Hozzászólások

Milyen disztró melyik verziója?

Üdv,
Marci

Mindegy is. :)

PowerShell telepítés így: https://github.com/PowerShell/PowerShell/blob/master/docs/installation/…
Megoldás PowerShell-ben:

Nevek listázása:

Get-ChildItem -Recurse -File -Force  | Where-Object {$_.LastWriteTime.Hour -lt 6} |  % { $_.FullName }

Megfelelő file-ok törlése:

Get-ChildItem -Recurse -File -Force  | Where-Object {$_.LastWriteTime.Hour -lt 6} |  Remove-Item

Üdv,
Marci

Talán nem kell hozzá Powershell...

$ find . -type f -newermt "00:00:00" ! -newermt "06:00:00" -exec rm {} \;

Okulni akartam, rákerestem...
Ha valaki érzékeny rá...

By default, PowerShell collects the OS description and the version of PowerShell (equivalent to $PSVersionTable.OS and $PSVersionTable.GitCommitId) using Application Insights. To opt-out of sending telemetry, delete the file DELETE_ME_TO_DISABLE_CONSOLEHOST_TELEMETRY before starting PowerShell from the installed location. The telemetry we collect fall under the Microsoft Privacy Statement.

...és ügyel, hogy ne matcheljen a filenév a regexre.
A pwsh évtizedekkel korszerűbb a Unix-os shellek szövegfeldolgozásánál, érdemes ennek az előnyeit kihasználni.
Ma egyre inkább igaz, hogy írd meg egyszer és futtasd utána ahol csak bírod - ebben a hagyományos shell scriptingnek fájdalmas hordozhatósági gondjai vannak.

Üdv,
Marci

Nem kell megtanulnom egy számomra nehézkes nyelvet csak azért, mert állítólag modern és hordozható, hanem használhatom azokat az eszközöket, amelyeket már megismertem és többé-kevésbé tudok is használni, és ráadásul multiplatform.

=====
tl;dr
Egy-két mondatban leírnátok, hogy lehet ellopni egy bitcoin-t?

Vagy print helyett printf, és úgy írja ki a dátumot, filenevet, akármit, ahogy szeretné. Mondjuk kiírja az mtime-ból az órát meg a fájl nevét, egy awk-kal a kimenetből kiválogatja azokat, ahol az első mező kisebb, mint 6, és kiírja a második mezőt (fájlnév) - ezt meg simán megeszi egy xargs rm, oszt' jó'van.

A find relative kevés fájl esetén príma, ha sok (tízezres nagyságrend és fölötte) fájl közül kell szelektálni, akkor azért verziótól függően marha lomha tud lenni (van, ami fájlonként legalább kettő stat/fstat hívással operál...) - pont ilyenre írtam anno Perl-ben egy aprócska toolt: felolvassa a könyvtárat, minden fájlra,a minek a neve illeszkedik a paraméterként megadott mintára indít egy darab stat-ot, és az abból kaptt idő(k) alapján listáz vagy töröl.

Perl-ben egy szösszenet:


use File::stat;

my $kvt = ".";

opendir( my $dh, $kvt ) || die "Can't opendir $kvt $!";
while ( readdir $dh ) {
    my $stat = stat($_);
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
      localtime $stat->mtime;

    if ( $hour > 18 ) {
        printf "%s\t%02d:%02d\n", $_, $hour, $min;
       # unlink $_;
    }

}

Jelen állapotban kiírja az aktuális könyvtárban azon fájloknak a nevét és a mtime-ból az óra:perc értéket, amiknél a készítés idejében az óra kisebb, mint 6. Ha az unlink-es sor elől kiveszed a "#"-et, akkor törli is az adott fájlt.

Elírtam, és te ügyesen lockoltad - ilyenkor nem az adott hsz.-ra válaszolunk, hanem sima hsz-ban jelezzük a problémát vagy privát üzenetet küldünk, etc, de nem vagy ennyire új fiú errefelé, hogy ezt magyarázni kéne neked... :-P

Egyébként Windows alatt szenvedek a kopipasztával meg az ablakváltással (Alt+TAB mesebeli, hol van, hol nincs, szerencsére a Win+TAB működik), úgyhogy erre is lehetne valami jó javaslat, hogy az alt+tab-ot mé' nem szereti néha ez a csoda jószág... :-)

Akkor már azt a ketyegő bombát sem tudod hatástalanítani, hogy a scripted könyvtárakat is visszaad és csak az unlink kegyessége menti meg azokat a törléstől. Viszont, ha valaki máshogy töröl, akkor robbanhat... :D
Finomítási lehetőség:

use File::stat;
use Fcntl ':mode';

my $kvt = ".";

opendir( my $dh, $kvt ) || die "Can't opendir $kvt $!";
while ( readdir $dh ) {
    my $stat = stat($_);
    my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
      localtime $stat->mtime;

    if ( $stat->mode & S_IFREG && $hour < 6 ) {
        printf "%s\t%02d:%02d\n", $_, $hour, $min;
       # unlink $_;
    }

}

Üdv,
Marci

Apró nüansznyi különbség, hogy (verziófüggően) van olyan find, ami minden fájlra, amit talál, csinál stat() és fstat() hívást _is_. Ha illeszkedik a teljes kifejezésre, akkor a tevékenységtől függően ezt akár meg is ismétli. (RHEL5/6 esetén láttam ilyet, ha jól rémlik). Százezres darabszám esetén azért marhára nem mindegy a legalább dupla darabszámú rendszerhívást megcsinálni....

Lehet, hogy itt nem, én ezzel csak arra szerettem volna felhívni a figyelmet, hogy a find jó, de van, amikor felejtős. Például a névre, időadatokra "lóugrásban" illeszkedő fájlok keresése tíz- meg százezer fájl között már lehet, hogy más módon közelebb lesz az optimálishoz.

A probléma nekem többszázezres-milliós számosságú fájlt tartalmazó, ext3-ra pakolt átmeneti könyvtáron jött elő - a cron-ból futtatott "find (cfra mintaillesztések sorozata) -mtime... satöbbi" parancs nem futott le belátható idő alatt, és kellett valami megoldás.
A strace alapján derült ki az adott find implementáció problémája a dupla-tripla stat/fstat rendszerhívásokkal, és erre készült gyors megoldásként egy perl script, ami az opendir, readdir, mintailleszt fájlnévre, ami ha illeszkedik, akkor stat, ha régi, akkor unlink folyamatot csinálta végig. Gyors lett, jóval gyorsab, mint más - lehet, hogy C-ben megírva még gyorsabb lett volna, de akkor és ott ez is elég volt.

Itt egyébként tényleg elég lehet a find -f , egy jól irányzott printf ("%Tk %p\n") aztán mögéakasztani egy awk '$1<6 { print $2}'-t, az egész kimenetét meg odaadni egy xargs rm-nek...

No, hadd legyen már itt egy pythonos megoldás is; nem túl hosszú, de pontosan azt teszi, amit akarunk; nincsennek side effect-ek, és elég jól olvasható.
sys.argv[1]: a parancssorban megadott könyvtár;
törlés: a "print" helyett os.remove(fpath);
tstart, tstop révén az időpont meghatározása nem mintaillesztéssel (regex,grep) történik;


#!/usr/bin/env python3
#-*- coding:utf-8 -*-

import os, sys, datetime as dt, os.path as op

tstart= dt.datetime(2013,5,2, 22,11,50)
tstop= dt.datetime(2013,5,2, 22,27,00)

for currentdir, subdirs, files in os.walk(sys.argv[1]):  
    for fname in files:
        fpath= op.join(currentdir,fname)
        dd= dt.datetime.fromtimestamp(op.getmtime(fpath))
        if tstart<=dd<=tstop:
            print(fpath, dd)

--
eutlantis