Finde filer af en bestemt type ud fra indholdet?
Som nævnt i denne tråd http://www.linuxin.dk/node/18913 har jeg genoprettet en masse filer fra en overskrevet NTFS partition.
Som altid når man gør dette, er mange af filerne ren junk selv de tilsyneladende er ok. Men når man så klikker på dem vil de ikke åbnes.
Derfor har jeg brug for at detektere hvilke af filerne som sandsynligvis er ok.
Kommandoen file kan bruges til dette, fx skriver den for gyldig fil (idet pptx-filer i virkeligheden er zip containere):
For en ugyldig skriver den bare data.
Mit spørgsmål er nu hvordan jeg kombinerer dette med find så den kopierer/flytter filer som genkendes af file kommandoen?
Hvis der er helt andre metoder, hører jeg også gerne om dette!
Som altid når man gør dette, er mange af filerne ren junk selv de tilsyneladende er ok. Men når man så klikker på dem vil de ikke åbnes.
Derfor har jeg brug for at detektere hvilke af filerne som sandsynligvis er ok.
Kommandoen file kan bruges til dette, fx skriver den for gyldig fil (idet pptx-filer i virkeligheden er zip containere):
file Presentation.pptx
Presentation SAS.pptx: Zip archive data, at least v2.0 to extract
For en ugyldig skriver den bare data.
Mit spørgsmål er nu hvordan jeg kombinerer dette med find så den kopierer/flytter filer som genkendes af file kommandoen?
Hvis der er helt andre metoder, hører jeg også gerne om dette!
Kommentarer9
Det er en værre pickle. Jeg
Det du gerne vil er basically at analysere på outputtet af find, hvorvidt der står "data" eller "noget andet". Hvis "noget andet" skal filen flyttes til en safe-mappe.
Personligt ville jeg strikke et PHP-script sammen til formålet. noget ala
foreach(glob('filerderskalanalyseres/*.pptx') as $filename){
ob_start();
system('file ' . $filename);
$output = ob_get_clean();
if($output!='data'){
system('mv ' . $filename . ' /den/folder/det/nu/skal/ligge/i');
}
}
det ovenstående skal tweakes til at passe situationen. fx tager den kun højde for pptx-filer, og den går ud fra at outputtet på korrupte filer er *præcist* strengen "data". dvs hvis der er whitespace før og efter, eller hvis der er noget "error:" eller hvis filnavnet er med i, så vil den flytte hver eneste fil. Så du skal lave en regular expression der passer præcist på det du forventer at få ud, ved en fejl.
quick and dirty bash
for i in `find *pox*`; do
ii=`file $i | grep -v data`;
if [ "$ii" != "" ];
then cp $i /newdisk/dir/;
fi;
done;
erstat find *pox* med din find streng og /newdisk/dir/ med det korrekte.
grep -v svarer til at søge efter hvis strengen ikke findes i file outputtet du kan selv tilpasse grep regexp.
Edit så at data faktisk indgår i outputtet for excel så du skal nok leje lidt mere med grep for kun at fange de filer der faktisk er invalide. der er også nogle filer som file repportere som data der ikke er korrupte.
grep -v ": data$" er et bedre bud end ovenstående.
Tak for ideen!Jeg var alt
Tak for ideen!
Jeg var alt for fokuseret på bash scripting som jeg ikke har ret godt styr på og tænkte slet ikke i php-baner som er mit ekspertområde.
Dit forslag kan bruges stort set uændret:
#!/usr/bin/php
<?php
foreach(glob('*.pptx') as $filename){
ob_start();
system('file ' . "'$filename'");
$output = ob_get_clean();
#echo $output;
if(preg_match('/Zip archive data, at least v2\.0 to extract/', $output)){
system('echo found: ' . $filename . "\n");
system('cp ' . "'$filename'" . ' ok-files');
}
}
?>
Og det kan let modificeres til fx word-dokumenter:
#!/usr/bin/php
<?php
foreach(glob('*.doc') as $filename){
ob_start();
system('file ' . "'$filename'");
$output = ob_get_clean();
#echo $output;
if(preg_match('/Template: .*\.dot/', $output)){
system('echo found: ' . $filename . "\n");
system('cp ' . "'$filename'" . ' ok-files');
}
}
?>
Det ser også ud til at
Det ser også ud til at kunne virke, men der er problemer med filer som indeholder mellemrum. Det får file i linje 2 til at fejle.
Så sæt gåseøjne
Så sæt gåseøjne rundt om $i
Så sæt gåseøjne
Det var min første indskydelse men det virkede ikke. Rodede dog ikke videre derefter idet php-løsningen fungerer fint.
Det var min første
Det eneste jeg er kommet fremtil er at bash variabler er noget hø hvis du har mellemrum. da bash tilkytter en semantisk betyding til whitespaces.
det virker fint med find|sed 's/ /\\ g/' hvis du forsøger at putte det i en variabel forsvinder \ og newline chars.
Det eneste jeg er kommet
I det hele taget synes jeg bash har en forfærdelig syntaks. Det er derfor jeg aldrig er kommet længere end til noob stadiet! Det irriterer mig, og så har jeg svært ved at tage mig sammen til at lære det ordentligt.
I det hele taget synes
For mig er det ikke så meget syntaksen men mere de underlige særheder der hele tiden er og ikke rigtigt er dokumenteret, jeg har selv problemer med at overskue lidt større ting, er primært breakfix tekniker og ikke programør.