Ubuntu Suomen keskustelualueet

Ubuntun käyttö => Ohjelmointi, palvelimet ja muu edistyneempi käyttö => Aiheen aloitti: pappor - 12.03.15 - klo:09.38

Otsikko: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: pappor - 12.03.15 - klo:09.38
Nyt on tullut hakattua päätä seinään(greppiä, findia jne.), mutta osaisiko joku viisampi heittää hyvän neuvon seuraavanlaiseen ongelmaan.

Olisi tarve hakea tietyn kellonajan välillä luodut tiedostot(joka päivä klo 1200 - 1205 välisenä aikana) ja kopioida ne eri hakemistoon, ongelma on nyt tuon aikavälin sisällä luotujen tiedostojen haku siten, että ne haetaan kaikkina päivinä.



Otsikko: Vs: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: welmar - 12.03.15 - klo:11.16
Joku muu saa kertoa kuinka tehdä paremmin mutta nopeasti kokeilin niin ainakin näin sen vois tehdä
Koodia: [Valitse]
ls -luta|grep 12:00 && ls -luta|grep 12:01 && ls -luta|grep 12:02 && ls -luta|grep 12:03 && ls -luta|grep 12:04 && ls -luta|grep 12:05 Jotenkin vain kuin sais niin ettei joka minuuttia tarvitsisi erikseen kirjoittaa niin kai toi muuten toimisi. Nyt vain kiire joten ehtinyt tämän enempää pohtia.
Otsikko: Vs: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: ajaaskel - 12.03.15 - klo:13.17
Joku muu saa kertoa kuinka tehdä paremmin mutta nopeasti kokeilin niin ainakin näin sen vois tehdä
Koodia: [Valitse]
ls -luta|grep 12:00 && ls -luta|grep 12:01 && ls -luta|grep 12:02 && ls -luta|grep 12:03 && ls -luta|grep 12:04 && ls -luta|grep 12:05 Jotenkin vain kuin sais niin ettei joka minuuttia tarvitsisi erikseen kirjoittaa niin kai toi muuten toimisi. Nyt vain kiire joten ehtinyt tämän enempää pohtia.

Vinkki: Useampia vaihtoehtoisia grep -ehtoja voi halutessaan antaa joko näin:

Koodia: [Valitse]
grep -E '12:00|12:01|12:02|12:03|12:04|12:05'
tai näin:

Koodia: [Valitse]
grep -e 12:00 -e 12:01 -e 12:02.... jne
Tuo "ls -luta" ei näytä aina kellon aikaa tiedostoille, ehkä "stat" hoitaisi tuon paremmin ?

Koodia: [Valitse]
stat -c "%y %n" ./*
Neljännen kentän tulosteesta saa helposti tällä:
Koodia: [Valitse]
cut -d' ' -f4
Sitten vain vaikka "xargs" syöttämään "cp" komennolle...  Tyylikkäämpi tapa silti olisi tehdä tuo "for" silmukalla.
Otsikko: Vs: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: New_user - 13.03.15 - klo:10.29
Tällaisen nyypiön kulmakarvat kohosivat melkoisesti, kun säiettä lukiessa selvisi, ettei näin perusjuttua, kuin tiedostojen hakemista aikaperusteisesti ole toteutettu käyttöjärjestelmätasolla.
Otsikko: Vs: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: ajaaskel - 13.03.15 - klo:10.46
Tällaisen nyypiön kulmakarvat kohosivat melkoisesti, kun säiettä lukiessa selvisi, ettei näin perusjuttua, kuin tiedostojen hakemista aikaperusteisesti ole toteutettu käyttöjärjestelmätasolla.
Aikaperusteisia hakuja löytyy oikeastaan runsaasti eri yhteyksissä. 

Tässä pieni silmukka joka tekee pyydetyn asian:

Koodia: [Valitse]
#!/bin/bash

mkdir -p ./valitut

for f in ./*; do
    minuutit=$(cut -d':' -f2  <<< $(cut -d' ' -f2 <<< "$(stat -c "%y %n" "$f")"))

    if [ "$minuutit" -ge "0" ] && [  "$minuutit" -le "5" ] && [ ! -d "$f" ]; then
       echo "Minuutit=$minuutit"  "tiedosto=$f"
       cp -a "$f" ./valitut
    fi
done


Tallenna jollekin nimelle, anna ajo-oikeus ja aja siinä kansiossa mistä haluat poimia tiedostot.  Koodi tekee sinne kansion "valitut" jonne tiedostot ilmestyvät.
En ole varma minkä ajan perusteella haluat poimia tuolla "stat": ssa, sen helppi näyttää:

 %y   time of last modification, human-readable
 %z   time of last change, human-readable

Selitys:  Tuo katsoo "stat"-komennon tulosteesta minuuttikentän ja kopiointi tehdään jos minuutit ovat rajojen sisällä ja kyseessä ei ole kansio. Piilotiedostot eivät kopioidu.
Otsikko: Vs: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: nm - 13.03.15 - klo:12.37
Tällaisen nyypiön kulmakarvat kohosivat melkoisesti, kun säiettä lukiessa selvisi, ettei näin perusjuttua, kuin tiedostojen hakemista aikaperusteisesti ole toteutettu käyttöjärjestelmätasolla.

Yleisesti käyttöjärjestelmätasolla eli tiedostojärjestelmässä on toteutettu vain hakemistohierarkian sekä tiedostojen metadatan ja sisällön tallennus. Kaikki haut tehdään näiden tietojen pohjalta userspacen puolella.

Tiedostojen etsimiseen soveltuva perustyökalu find tukee kyllä useita yleisesti tarvittavia aikapohjaisia hakuja, mutta tällainen päivittäinen tiettyjen kellonaikojen välinen intervalli ei onnistu suoraan, vaan päivämäärä on määriteltävä:

Koodia: [Valitse]
find . -newermt "2015-03-01 11:59:59" -and -not -newermt "2015-03-03 12:06:00"

Sen perusteella voisi siis kikkailla jotain tällaista:

Koodia: [Valitse]
#!/bin/sh

for year in $(seq 2000 2015); do
    for day in $(seq 0 365); do
        dt=$(date --date "$year-01-01 + $day days" "+%Y-%m-%d")
        find "$1" -newermt "$dt 11:59:59" -and -not -newermt "$dt 12:05:00" -exec cp -a "{}" /polku/kohdehakemistoon/ \;
    done
done

Tämä ei kuitenkaan ole erityisen hyvä ratkaisu, koska find-komento ajetaan uudelleen jokaisen päivän kohdalla ja se käy kaikki annetun hakemiston tiedostot läpi.

Alla statin antaman aikaleiman vertailuun perustuva tehokkaampi skripti, joka käy annetut tiedostot läpi vain yhden kerran:

Koodia: [Valitse]
#!/bin/sh

for f in "$@"; do
    mtime=$(stat -c "%y" "$f" | cut -d' ' -f2)
    hour=$(echo "$mtime" | cut -d: -f1)
    min=$(echo "$mtime" | cut -d: -f2)
    if [ "$hour$min" -ge "1200" ] && [ "$hour$min" -lt "1205" ]; then
        cp -a "$f" /polku/kohdehakemistoon/
    fi
done

Lisäys: ajaaskel ehtikin lisätä viestiinsä samansuuntaisen ratkaisun, mutta jätetään tämäkin esille
Otsikko: Vs: Tiedostojen haku tietyllä aikavälillä
Kirjoitti: SuperOscar - 13.03.15 - klo:20.58
Minulta yleensä loppuu (ba|z)?sh-skriptaus, jos jonkin kanssa joutuu taistelemaan tosissaan, ja kirjoitan homman Pythonilla.

Tässä testaamaton esimerkki, johon oikeassa käytössä kannattaisi varmaan lisäillä try…except-lohkoja sopivasti:

Koodia: [Valitse]
#!/usr/bin/env python3

import os
import datetime
import shutil

dest = './valitut'
if not os.path.isdir(dest):
    os.mkdir(dest)

for fname in os.listdir():
    ctime = datetime.datetime.fromtimestamp(os.stat(fname).st_ctime)
    if ctime.hour == 12 and 0 <= ctime.minute <= 5:
        shutil.copyfile(fname, os.path.join(dest, fname))