[PERL]Przypadkowe usuwanie plików!

Bash, C, C++, Java, PHP, Ruby, GTK, Qt i wiele innych - wszystko tutaj.
Agent_0-700
Piegowaty Guziec
Piegowaty Guziec
Posty: 3
Rejestracja: 03 gru 2008, 11:53
Płeć: Mężczyzna
Wersja Ubuntu: 8.10
Środowisko graficzne: GNOME

[PERL]Przypadkowe usuwanie plików!

Post autor: Agent_0-700 »

Witam!

Jestem początkującym programistą PERL-A i mam spory problem: stworzyłem następujący skrypt do masowej zmiany nazwy plików:

Kod: Zaznacz cały

#!/usr/bin/perl
opendir(HU, ".");
@hu=readdir(HU);
closedir(HU);

foreach $hu(@hu) 
{
	if ($hu =~ /_at_/) 
	{
		my $poz_pocz;
		my $poz_konc;
		my $us = 1;
		$poz_pocz=index($hu, "_at_")+3;
		my $czesc_nazwy= substr($hu, $poz_pocz);
		#print "$czesc_nazwy \n";
		for $a (0..2)					 #wartosc "2" oznacza liczbe
		{						 #znakow "_" pomniejszona o 
			my @znaki=index($czesc_nazwy, "_")+1;	 #1. oznacza to, ze gdy w 
			#print "@znaki oraz $us\n";		 #skrypcie bedzie 2, usunie
			$us=@znaki[a];				 #sie 2 slowa miedzy trzema 
			$czesc_nazwy= substr($czesc_nazwy, $us); #znakami "_"
			#print "$czesc_nazwy \n";
		}
		$pocz=substr($hu, 0, $poz_pocz);
		@nazwa = ($pocz, $czesc_nazwy);
		$nowa_nazwa=join("_", @nazwa);
		#print "$pocz i $czesc_nazwy oraz @nazwa\n";
		#print "nowa nazwa to $nowa_nazwa \n";
		rename($hu, $nowa_nazwa);
	}
}
#my $wait=<stdin>;
exit;
Konkretnie skrypt ma za zadanie zmienić nazwę plików w ten sposób, aby usunąć trzy podkreślenia (czyli znaki "_") po słowie "_at_" oraz oczywiście wszystko co jest pomiędzy nimi. Czyli w przypadku nazwy pliku:

Kod: Zaznacz cały

222_moje_at_pale_szlugi_plik_testowy.txt
efekt powinien być następujący:

Kod: Zaznacz cały

222_moje_at_plik_testowy.txt
Po pierwszym uruchomieniu skryptu wszystko wychodzi jak należy. Jednak po ponownym uruchomieniu skryptu (zakładam przypadkowe ponowne uruchomienie) czasem skraca nazwę do:

Kod: Zaznacz cały

222_moje_at_testowy.txt
a czasem całkowicie go usuwa!!! Oczywiście najlepszym rozwiązaniem byłoby zupełne wyeliminowanie obu problemów, ale chyba tego zrobić się nie da. Dlatego chciałbym przynajmniej skupić się na tym usuwaniu plików. Żeby było śmieszniej, gdy zamiast "222" w nazwie pliku jest np. "xxx", nawet wielokronte uruchomienie skryptu nie powoduje usunięcia pliku.
Czy jest jakiś sposób aby skrypt nie usuwał tych plików? Myślałem nad sprawdzaniem długości zmiennej "$czesc_nazwy", ale to bez sensu, bo pliki, na których ma skrypt operować moga mieć różną długość (pczy czym na 100% większą od tych 3 podkreśleń po "_at_").

Czy jest ktoś, kto zna rozwiązanie tego problemu?


/EDIT
Być może ważnym faktem jest to, że skrypt jest uruchamiany na Windowsie XP
otokan
Sędziwy Jeż
Sędziwy Jeż
Posty: 65
Rejestracja: 11 gru 2008, 11:20
Płeć: Mężczyzna
Wersja Ubuntu: 10.04
Środowisko graficzne: GNOME
Architektura: x86

Odp: [PERL]Przypadkowe usuwanie plików!

Post autor: otokan »

Ogólnie zamiast zabawy substringami proponuje wykorzystać prawdziwą moc perla: wyrażenia regularne.

Polecenie

Kod: Zaznacz cały

s/_at_(?:.+?_){2}/_at_/;
usuwa dwa kolejne słowa (za ciągiem _at_) oddzielone znakiem _ ze zmiennej $_.
Z powodzeniem zastąpi ono 90% Twojego kodu.

Ponowne uruchomienie polecenia nie będzie nic psuło pod warunkiem, że w nazwach oryginalnych plików nie było więcej niż 4 słowa oddzielone _ za fragmentem _at_.

Pliki Ci znikaja zapewne dlatego ze robisz rename wielu plików na jedną nazwę nadpisując plik za każdym razem.

p.s. dodaj

Kod: Zaznacz cały

use warings;
use strict;
na początku skryptu.
Agent_0-700
Piegowaty Guziec
Piegowaty Guziec
Posty: 3
Rejestracja: 03 gru 2008, 11:53
Płeć: Mężczyzna
Wersja Ubuntu: 8.10
Środowisko graficzne: GNOME

Odp: [PERL]Przypadkowe usuwanie plików!

Post autor: Agent_0-700 »

Skrypt testowałem przy wielu plikach i paradoksalnie wtedy wszystko jest w jak najlepszyp porzadku. Dopiero w sytuacji, w której w folderze, w którym uruchamiam skrypt jest jeden plik to czasami dzieją sie te cuda z usuwaniem.
Co do wyrażeń, to po prostu nie wiedziałem jak sformułowac odpowiednie, więc dzięki:)
Natomiast długość nazw plików jest mniej-więcej taka jak w przykładzie, więc bardzo prawdopodobne iż po jednokrotnym uruchomieniu, które skróci nazwę o 2 słowa oddzielone "_" zostanie wystarczająco dużo słów by to skrócić jeszcze raz. No ale jak już mówiłme - wiem, że tego od strony skryptu się raczej nie załatwi.
ODPOWIEDZ

Wróć do „Programowanie”

Kto jest online

Użytkownicy przeglądający to forum: Amazon [Bot] i 8 gości