Skocz do zawartości

Skrypt Wyszukujący Błednie Zapisane Pliki


samba

Rekomendowane odpowiedzi

Witam

Mam udział samby na którym mam skany .Każdy katalog to rok np mam katalog 2009 i w tym katalogu są pliki 1_09.tif 2_09.tif czyli cyfra _09(rok).tif .

Dopuszczalny jest jeszcze zapis liczba_liczba_rok.tif np 124_1_09.tif.

Analogicznie jest dla innych lat tj np mam katalog 2008 a w nim pliki liczba_08.tif.

 

Teraz chcę dodać do Crona skrypt który co jakiś czas będzie sprawdzał w każdym katalogu czy nie ma błedu tj. czy ktoś zapisał plik z roku 09 do katalogu np 2007 i na odwrót , czyli wyszukiwanie w katalogu 2007 wszystkich rozszeżeń (lat) innych niż 07 czyli _05 _06 _08 itd i tak dla wszystkich lat.

 

Jeśli skrypt znajdzie błąd to najlepiej aby zapisał w pliku tekstowym źle zapisane nazwy plików, czyli np jeśli znajdzie błąd w katalogu 2007 to skrypt ma zrobić > 2007_błędy.txt a w tym pliku np. 124_09.tif .

 

Macie jakieś pomysły .

Poza tym czy znak "_" w grepie nie jest znakiem specjalnym ? jak go zacytować?

Odnośnik do komentarza
Udostępnij na innych stronach

Zawsze zadziała backslash "\", ale to nie jest znak specjalny dla grep.

Poza tym dlaczego grep jeśli mówimy o nazwach plików a nie o ich zawartości? Nie lepiej zastosować find?

Cześć Waldo masz racje mówimy o nazwach plików ale grep ma o wiele większe możliwości parsowania niż find. ls w połączeniu z grepem jest o wiele szybszym rozwiązaniem niż ociężałe find.

Na razie wymyśliłem coś takiego :

np w katalogu 2007 robię

 ls |sort |grep _ > blendy_w_2007.txt [code]

 

Nie wiem jak zrobić "zapytanie" aby grep wyszukał mi po znaku "_" (podkreślenie dolne) każdej cyfry innej niż 07 ???

Przykład:

Jeśli w katalogu 2007 mam pliki np 123_07.tif to ich nie wyszukuję bo tylko takie powinny się w nim znajdować.

 

Natomiast wszystkie inne np 123_09.tif lub 123_08.tif już nie bo to są błędnie skopiowane/zapisane i powinny się znajować w innym katalogu czyli tu w tym przykładzie w 2009 lub 2008 r.

 

Wtedy w cronie zrobiłbym dla każdego katalogu z rokiem takie wyszukiwanie zmieniałym tylko cyferki których nie chcę wyszukiwać.

Wiem że to jest takie "rozwiązanie na około" ale bardzo by mi pomogło i wydaje się szybkie.

 

Polecenie find obciąża dyski wyszukiwaniem i o wiele dłużej trwa, natomiast ls + grep + inne wyrażenia regularne są szybsze.

Odnośnik do komentarza
Udostępnij na innych stronach

Nie wiem jak zrobić "zapytanie" aby grep wyszukał mi po znaku "_" (podkreślenie dolne) każdej cyfry innej niż 07 ???

Przykład:

Jeśli w katalogu 2007 mam pliki np 123_07.tif to ich nie wyszukuję bo tylko takie powinny się w nim znajdować.

 

Natomiast wszystkie inne np 123_09.tif lub 123_08.tif już nie bo to są błędnie skopiowane/zapisane i powinny się znajować w innym katalogu czyli tu w tym przykładzie w 2009 lub 2008 r.

grep -v "_07"

przy czym frazę warto uzupełnić odpowiednim kontekstem.

man grep jest dość dobrze napisany.

 

Odnośnik do komentarza
Udostępnij na innych stronach

 

moze cs takiego:

 

echo "Testuje pliki w folderze 2009"; find . | awk -F/ '$2=2009 {print $3}'|egrep -v "[0-999999999]_09.tif|^$" > output.txt

a moze mailem chcesz codziennie?

echo "Testuje pliki w folderze 2009"; find . | awk -F/ '$2=2009 {print $3}'|egrep -v "[0-999999999]_09.tif|^$"|mail -s "pliki do bani" [email protected]

oczywiscie pliki w arachiwum powinienes podpisac :) min md5 :)

Odnośnik do komentarza
Udostępnij na innych stronach

moze cs takiego:

 

echo "Testuje pliki w folderze 2009"; find . | awk -F/ '$2=2009 {print $3}'|egrep -v "[0-999999999]_09.tif|^$" > output.txt

 

Witam

Dzięki za pomoc . Próbowałem twojego wpisu ale niestety nic w pliku output.txt nie ma tzn nie wyszukuje błędnie zapisanych plików a takowe występują.

Mam parę pytań do twojego skryptu.

 

Po pierwsze o co chodzi z find . ? Co da kropka? nie kapuje dalszej cześci tj awk -F/ '$2=2009 {print $3}'

 

Po drugie myślę iż 0-999999 jest nie potrzebne ponieważ wyszukujemy błędów po znaku "_" oraz cyfr innych niż 09 czyli "_09.tif". Reasumując pliki które wyglądają tak : np 1455_09.tif 140_09.tif są ok a my mamy za zadanie wyszukać roku czyli to co jest po "_"

i jest w tym przypadku inne niż _09.tif

 

Dzięki waszej pomocy YSIO i JJJ naprowadziliście mnie na inne prostsze rozwiązanie !!!

ls -all |egrep -v "_09.tif|^$" > blendy.txt

 

W tym momencie dostaje takie wyjście

drwxrwxr-x  2 fujitsu skanery    12288 III 31 08:56 .
    4 drwxrwxr-x 23 fujitsu  skanery     4096 III 30 14:11 ..
    0 -rwxrwxrwx  1 fujitsu skanery        0 III 31 08:55 08_09.psd
    0 -rw-r--r--  1 root    root           0 III 30 22:38 123_08.tif
1744 -rwxrwxrwx  1 fujitsu skanery  1778072 III 31 08:56 25-09.tif
    4 -rw-r--r--  1 root    root         453 III 31 08:59 blendy.txt
    0 -rwxrwxrwx  1 fujitsu skanery        0 III 31 08:55 Nowy IrfanView BMP File.bmp

Jedyne co potrzebuje to rok. I tu kolejne pytanie jak w FC7 wyciagnąć rok?? ls --full-time pokazuje mi zbyt wiele zbędnych rzeczy a samo ls -all nie pokazuje roku utworzenia pliku ?!!

Po drugie zastanawiam się jak taki skrypt można jeszcze zautomatyzować ( skrypt uruchomi Cron) jeśli chodzi o katalogi tj

w katalogu skany mam podkatalogi

2006

2007

2008

2009

 

I teraz dodając do crona skrypt musiałbym dla każdego katalogu pisać odzielną linijkę tj

ls -all |egrep -v "_06.tif|^$" > blendy.txt

ls -all |egrep -v "_07.tif|^$" > blendy.txt

ls -all |egrep -v "_08.tif|^$" > blendy.txt

itd

 

Może macie jakieś rozwiązanie aby hurtem przelecieć katalog skany z podkatalogami i wyszukać błędne pliki dla każdego katalogu?

 

UPDATE

 

Zrobiłem taki skrypt

#!/bin/bash
ls -all /mnt/skany/skany/2005/ |egrep -v "_05.tif|^$" > blendy.txt
ls -all /mnt/skany/skany/2006/ |egrep -v "_06.tif|^$" > blendy.txt
ls -all /mnt/skany/skany/2007/ |egrep -v "_07.tif|^$" > blendy.txt
ls -all /mnt/skany/skany/2008/ |egrep -v "_08.tif|^$" > blendy.txt
ls -all /mnt/skany/skany/2009/ |egrep -v "_09.tif|^$" > blendy.txt

 

Gdy ręcznie uruchomię ./skrypt Mam problem ponieważ skrypt nie wykonuje się w powyższej lokalizacji tj /mnt/skany/skany/katalog

tylko szuka w miejscu gdzie fizycznie przebywa plik skryptu?? Nie rozumiem dlaczego tak się dzieje, przecież wskazałem ścieżkę ?

Czy pozostaje mi nic innego jak dopisanie przed każdym wierszem cd /mnt/skany/skany/2005 itd ???

Edytowane przez WalDo
domknięcie tagu quote
Odnośnik do komentarza
Udostępnij na innych stronach

Co da kropka?
Oznacza "Szukaj od bieżącego katalogu". Tak jak "find /" szukaj od głównego, "find /etc" szukaj od /etc itp

 

nie kapuje dalszej cześci tj awk -F/ '$2=2009 {print $3}'
Oznacza: dla programu awk ustaw znak "/" jako separator pól. Do pola numer 2 przypisz wartość 2009 i wypisz pole numer 3. I to jest chyba błąd. Prawdopodobnie miało być $2==2009 i wtedy oznaczałoby: gdy pole numer 2 jest równe 2009 to wypisz pole numer 3 (nie analizowalem dokładnie skryptu, więc mogę się mylić - tak na pierwszy rzut oka mi nie pasuje).

 

ls --full-time pokazuje mi zbyt wiele zbędnych rzeczy
Skoro zaczęliśmy korzystać z awk to może:
ls --full | awk '{ print $6"  "$9}'

a samo ls -all nie pokazuje roku utworzenia pliku ?
Tylko w przypadku plików nie starszych niż bodajże rok od dzisiaj. Dla plików starszych niż rok masz już wypisany rok w dacie.

Nota bene opcja "-all" to tylko opcja "-a" i powtórzona dwukrotnie opcja "-l" - wystarczyloby samo "-al". Oczywiście wynik będzie ten sam, więc to bez znaczenia. → "man ls" :)

 

Trochę problemów może Ci sprawić dość egzotyczny format daty jaki pojawił się w F7 (miesiąc pisany rzymską cyfrą dla polskiej wersji językowej). Jak poszukasz na forum, to chyba były jakieś poprawki na to. Być może, że aktualizacja systemu by wystarczyła - nie pamiętam już dokladnie jak to było.

 

 

Odnośnik do komentarza
Udostępnij na innych stronach

Trochę problemów może Ci sprawić dość egzotyczny format daty jaki pojawił się w F7 (miesiąc pisany rzymską cyfrą dla polskiej wersji językowej). Jak poszukasz na forum, to chyba były jakieś poprawki na to. Być może, że aktualizacja systemu by wystarczyła - nie pamiętam już dokladnie jak to było.

 

Dzięki Waldo za wyjaśnienie faktycznie w tamtym skrypcie jest błąd i chyba gdzieś jeszcze ale nie maiłem czasu tego analizować.

Zrobiłem coś takiego

#!/bin/bash
cd /mnt/skany/skany/2005/
ls -al /mnt/skany/skany/2005/ |egrep -v "_05.tif|^$" > blendy.txt
cd /mnt/skany/skany/2006
ls -al /mnt/skany/skany/2006/ |egrep -v "_06.tif|^$" > blendy.txt
cd /mnt/skany/skany/2007
ls -al /mnt/skany/skany/2007/ |egrep -v "_07.tif|^$" > blendy.txt
cd /mnt/skany/skany/2008
ls -al /mnt/skany/skany/2008/ |egrep -v "_08.tif|^$" > blendy.txt
cd /mnt/skany/skany/2009
ls -al /mnt/skany/skany/2009/ |egrep -v "_09.tif|^$" > blendy.txt

 

Dodałem do crona i na razie śmiga jest trochę na około ale ładnie pokazuje to co chciałem :)

 

Jak ktoś miałby jeszcze jakieś inne wskazówki to proszę piszcie .

Dzięki wszystkim za pomoc !

Pozdrawiam

Odnośnik do komentarza
Udostępnij na innych stronach

Przede wszystkim for. Pętla for.

for zmienna in lista; do
wykonaj to używając $zmienna
done

czyli np

for rok in 05 06 07 08 09; do
cd "/mnt/skany/skany/20$rok"
ls itd itd... | grep -v "_$rok" > bleeeedy.txt
done

Pętla mogłaby oczywiście operować na liście katalogów:

for rok in `ls -d /mnt/skany/skany`; do

Po drugie używaj >> zamiast > żeby nie tracić poprzedniego loga. Ważne zwłaszcza, kiedy chcesz mieć jeden egzemplarz loga ze wszystkich katalogów. To jest chyba Twój przypadek opisany w http://forum.fedora.pl/index.php?showtopic...st&p=121822

Po trzecie wiem z doświadczenia, że na początku porcji loga warto dopisać datę jej generowania.

Odnośnik do komentarza
Udostępnij na innych stronach

nie ma zadnego bledu :)

zakladam ze masz taka konfiguracje /dir1/dir2/dir3/archiwum/2009/1234567_09.tif

kod ktory masz wykonac to:

 

cd /dir1/dir2/dir3/archiwum
pwd
/dir1/dir2/dir3/archiwum
ls
2007
2008
2009
echo "Testuje pliki w folderze 2009"; find . | awk -F/ '$2=2009 {print $3}'|egrep -v "[0-999999999]_09.tif|^$" > output.txt

 

jezeli chcesz zrozumiec o co chodzi w tym potoku podziel go "|" wykonaj 1-sza czesc czyli

find .

pozniej dodaj 2-ga czesc czyli:

find . | awk -F/ '$2=2009 {print $3}'

itp

a zanim zaczniesz przerabiac

man find

man awk

man egrep

 

find .
./2009
./2009/140_09.tif
./2009/jolo_09.tif
./2009/1455_09.tif
echo "Testuje pliki w folderze 2009"; find . | awk -F/ '$2=2009 {print $3}'|egrep -v "[0-999999999]_09.tif|^$"
Testuje pliki w folderze 2009
jolo_09.tif

a wydawac sie moglo ze echo "" wszystko tlumaczy :)

oczywisci nic nie stoi na przeszkodzie zeby zapetlil te linie + sprawdzil czy faktycznie to katalog

cd cos tam/archiwum
for rok in 20*; do
if -d $rok]; then
echo "Testuje pliki w folderze $rok"; find . | awk -F/ '$2=$rok {print $3}'|egrep -v "[0-999999999]_09.tif|^$" > output.txt
elseif
echo $rok nie jest katalogiem
fi
done

tego ostatniego nie chce mi sie juz testowac i czy to ma sens

Odnośnik do komentarza
Udostępnij na innych stronach

nie ma zadnego bledu :)
No nie całkiem ;) Warunek $2=2009 (przypisanie) jest zawsze prawdziwy i równie dobrze może go nie być. Przypisanie ($2=2009) to nie to samo co porównanie zawartości ($2==2009).

Żeby uniknąć dalszej dyskusji i pokazać o co chodzi zrobiłem mały test.

 

Testowa struktura plików i katalogów

[test@vbox archiwum]$ find . 
.
./2008
./2008/123_08.tif
./2007
./2009
./2009/1234567_09.tif
./2009/1234567_08.tif
[test@vbox archiwum]$

i teraz trzy przykłady (tylko find i awk, grep pomijam bo nie jest tutaj istotny, to tylko filtr wyjścia). Dla uwidocznienia niepoprawności warunku dodałem wypisywanie pola $2.

[test@vbox archiwum]$ find . | awk -F/ '$2=2009 {print $2"-"$3}'
2009-
2009-
2009-123_08.tif
2009-
2009-
2009-1234567_09.tif
2009-1234567_08.tif

Bez podania warunku

[test@vbox archiwum]$ find . 
.
./2008
./2008/123_08.tif
./2007
./2009
./2009/1234567_09.tif
./2009/1234567_08.tif
[test@vbox archiwum]$

Z poprawnym warunkiem

[waldek@vbox archiwum]$ find . | awk -F/ '$2==2009 && $3!="" {print $3}'
1234567_09.tif
1234567_08.tif

Odnośnik do komentarza
Udostępnij na innych stronach

No nie całkiem ;) Warunek $2=2009 (przypisanie) jest zawsze prawdziwy i równie dobrze może go nie być. Przypisanie ($2=2009) to nie to samo co porównanie zawartości ($2==2009).

Żeby uniknąć dalszej dyskusji i pokazać o co chodzi zrobiłem mały test.

ehh przypisanie nastepuje w taki sposob zmienna1=1; zmienna2=2 ,a nie przez $zmienna1=1 (przynajmniej w sh)

przyklady podane sa slabe

find . | awk -F/ '$2=2009 {print $2"-"$3}'
find . | awk -F/ '$2==2009 && $3!="" {print $3}'

poniewaz daja rozny wynik gdyz zastosowales dotatkowy warunek w 2 przykładzie: tj. $3!="" {print $3}

zauwaz ze taki samo output dostaniesz:

find . | awk -F/ '$2=2009 && $3!="" {print $3}'

prawdopodbnie nie trzeba nawet sostoswac && i wystarczy

find . | awk -F/ '$2=2009 $3!="" {print $3}'

nie mam teraz dostepu do shella, wiec sprawdze to wieczorem dopiero

pozdro

Odnośnik do komentarza
Udostępnij na innych stronach

ehh przypisanie nastepuje w taki sposob zmienna1=1; zmienna2=2 ,a nie przez $zmienna1=1 (przynajmniej w sh)
No właśnie - w sh a w programie dzialasz w awk.

Podstawą błędu jest tutaj - jak sam napisałeś - użycie znaku "=" w taki sposób jak to jest wykorzystywane w sh.

awk wykorzystuje do przypisywania i porównywania składnię języka C i nic w tym dziwnego - to "k" w nazwie programu pochodzi o nazwiska Kernighana, jednego z twórców języka C (pozostali autorzy to Aho i Weinberger).

 

przyklady podane sa slabe
Dodatkowy warunek w ostatnim przykładzie wycina tylko linię, która nie ma 3. pola ($3) a właściwie ma to pole puste. Linia ta zawiera tylko "./2009" bez kolejnego slasha i nazwy pliku, więc w programie wyszukującym błedne pliki w podkatalogach jest zbędna.

 

Zresztą łatwo sprawdzić to co napisałem, bo podałem strukturę plików na jakiej przetestowałem polecenia.

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
×
×
  • Dodaj nową pozycję...