[+] Bash, usuwanie plików za pomoc

Potrzebujesz pomocy z C, C++, perl, python, itp.
daniel1302
Posty: 10
Rejestracja: 15 maja 2012, 20:58

[+] Bash, usuwanie plików za pomocą wyrażeń regularnych

Post autor: daniel1302 »

Witam.
M
am dosyć dużo plików (generowanych dynamicznie) o nazwach

Kod: Zaznacz cały

* 00[1-2][0-9]
Czyli np.:

Kod: Zaznacz cały

plik 0010
plikfdsa 0012
bleble 0029
I chciałbym usunąć wszystkie pliki, które mają 2 ostatnie liczby większe od 14.

Próbowałem zrobić tak:

Kod: Zaznacz cały

#! /bin/bash
rm /mnt/sdb2/daniel/ow/`.*\ 00\(15\|16\|17\|18\|19\|20\|21\|22\|23\|24\|25\|26\|27\|28\|29\)\+`
jednak nie działa. Wyświetla informację, że:

Kod: Zaznacz cały

/mnt/sdb2/daniel/ow/ jest katalogiem.

Proszę o pomoc. Z góry dziękuję.
Awatar użytkownika
lessmian2
Member
Posty: 1088
Rejestracja: 30 kwietnia 2008, 19:38
Lokalizacja: Kraków

Post autor: lessmian2 »

Czy zadałeś sobie odrobinę trudu i zajrzałeś do pomocy programu rm?

Kod: Zaznacz cały

...
Domyślnie rm nie usuwa katalogów. Użyj opcji --recursive (albo -r albo -R)
...
Swoją drogą, wątpię żeby Twoja konstrukcja zadziałała ;)
daniel1302
Posty: 10
Rejestracja: 15 maja 2012, 20:58

Post autor: daniel1302 »

Nie chcę usunąć katalogów tylko pliki z końcówką, która jest liczbą od 15 do 29. Próbowałem użyć wyrażeń regularnych ale polecenie rm chyba ich nie obsługuje.
Awatar użytkownika
kodama
Junior Member
Posty: 633
Rejestracja: 23 maja 2010, 22:30
Lokalizacja: Poznań

Post autor: kodama »

No to nie możesz tego zrobić prostą pętlą while z if? Ja na szybko to bym zrobił tak:

Kod: Zaznacz cały

#!/bin/bash
rm /tmp/t
cd  ...  #tu katgalog, w którym są te pliki
ls > /tmp/t

 while read line;
 do f=`echo $line | tail -c 3`

         if [ "$f" -ge 14 ]; then
         rm "$line";
         fi

 done</tmp/t
Edycja:
Teraz tak widzę, że chcesz usunąć pliki z przedziału 15 - 29, więc mój skrypt wymagałby modyfikacji delikatnej, ale to teraz tego nie napiszę, bo piszę z tableta, a to dziadostwo strasznie niewygodne. Do if-a trzeba warunek drugi dodać.

Edycja2
Linijka z if'em powinna być taka:

Kod: Zaznacz cały

if [ "$f" -ge 14 ] && [ "$f" -le 29 ]; then
sethiel
Junior Member
Posty: 762
Rejestracja: 28 stycznia 2008, 11:50
Lokalizacja: Wrocław

Post autor: sethiel »

Skutek taki sam tylko bez wyrażeń regularnych (regexp), też w tychże wyrażeniach kuleję więc może ktoś by podpowiedział jak w temacie.
Awatar użytkownika
kodama
Junior Member
Posty: 633
Rejestracja: 23 maja 2010, 22:30
Lokalizacja: Poznań

Post autor: kodama »

Ale działa.
Wyrażenia regularne to są "czary" :) A napisanie takiego skryptu to zajmuje, ile, 3 minuty?
Awatar użytkownika
lessmian2
Member
Posty: 1088
Rejestracja: 30 kwietnia 2008, 19:38
Lokalizacja: Kraków

Post autor: lessmian2 »

Oj tam, oj tam. Wyrażenia regularne są bardzo ciekawym tematem i bardzo często się przydają.

Jeśli na pewno chodzi Ci o pliki, które w nazwie mają dwie ostatnie dwucyfrowe liczby większe niż 14, to poniżej rozwiązanie. W katalogu mam pliki o nazwach od '0' do '9999', w sumie prawie 15000 plików.

Kod: Zaznacz cały

$ shopt -s extglob
$ ls -ln +(?)@(+([1][4-9]|[2-9][0-9]))@(+([1][4-9]|[2-9][0-9])) | head
-rw-r--r-- 1 1000 513 0 01-24 21:14 01414
-rw-r--r-- 1 1000 513 0 01-24 21:14 01415
-rw-r--r-- 1 1000 513 0 01-24 21:14 01416
-rw-r--r-- 1 1000 513 0 01-24 21:14 01417
-rw-r--r-- 1 1000 513 0 01-24 21:14 01418
-rw-r--r-- 1 1000 513 0 01-24 21:14 01419
-rw-r--r-- 1 1000 513 0 01-24 21:14 01420
-rw-r--r-- 1 1000 513 0 01-24 21:14 01421
-rw-r--r-- 1 1000 513 0 01-24 21:14 01422
-rw-r--r-- 1 1000 513 0 01-24 21:14 01423
Z oczywistych względów wkleiłem tylko kilka pierwszych linii. Sprawdź czy robi to o co Ci chodzi i miłego korzystania z wyrażeń regularnych ;)
Awatar użytkownika
markossx
Beginner
Posty: 489
Rejestracja: 26 maja 2007, 16:01
Lokalizacja: Polska

Post autor: markossx »

Dla tych konkretnych plików zadziałałbym tak:

Kod: Zaznacz cały

find . -type f -print | egrep '^./[a-z]*\ 00([1][4-9]|[2-9])' | xargs -I {} rm -v {}
.
sethiel
Junior Member
Posty: 762
Rejestracja: 28 stycznia 2008, 11:50
Lokalizacja: Wrocław

Post autor: sethiel »

A może jednak tak (zmieniłem or | )?

Kod: Zaznacz cały

find . -type f -print | egrep '^./[a-z]*\ 00([1][4-9]|[2][0-9])' | xargs -I {} rm -v {}
Część poprosiłbym o wyjaśnienie
egrep '^./[a-z]*\ 00([1][4-9]|[2][0-9])'
' ' - wyrażenie regularne - definicja, jak cudzysłów, całość
^./ - ?
[a-z]z przedziału od a do z
* połączone z, a może rekursywnie?
\ - znak specjalny spacja
00 - dwa pierwsze znaki zero
() - funkcja
| - or
i tutaj właśnie:
[1][4-9]|[2][0-9] - oznacza [1][4-9] lub [2][0-9] czy [1][4-9] lub [2] i [0-9]
hmm.
Awatar użytkownika
markossx
Beginner
Posty: 489
Rejestracja: 26 maja 2007, 16:01
Lokalizacja: Polska

Post autor: markossx »

Mam nadzieję, że zrobiłeś labka z kilkoma plikami :)
Twoja poprawka powoduje, że regex nie zadziała właściwie dla szukanych plików, sprawdzałeś?
Spróbuję Ci nieco to wyjaśnić ale muszę wiedzieć, że sam chcesz to połapać.

Kod: Zaznacz cały

 

'^./[color=#ff0000]1[/color][a-z]*[color=#ff0000]2[/color]\ [color=#ff0000]3[/color]00([1][4-9]|[2-9])'

1 początek nazwy pliku to przecież './' (^ w tym wypadku "na początku")
2 [a-z] po './' ma być litera z zakresu, następnie cokolwiek '*'
3 dalej potrzebujemy spację '\ '

póki co otrzymamy wynik:

"./ala "
"./ola "

odrzucimy na przykład:
"./alla"
"./9aaaaaa "

itd...
Resztę mam nadzieję Ty nam przybliżysz.
ODPOWIEDZ