Strona 1 z 2

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

: 21 stycznia 2013, 14:53
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ę.

: 21 stycznia 2013, 22:23
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 ;)

: 22 stycznia 2013, 07:46
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.

: 22 stycznia 2013, 08:59
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

: 24 stycznia 2013, 15:32
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.

: 24 stycznia 2013, 16:07
autor: kodama
Ale działa.
Wyrażenia regularne to są "czary" :) A napisanie takiego skryptu to zajmuje, ile, 3 minuty?

: 24 stycznia 2013, 21:28
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 ;)

: 25 stycznia 2013, 10:51
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 {}
.

: 25 stycznia 2013, 13:02
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.

: 25 stycznia 2013, 14:37
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.