Det er min erfaring, at scripting i enten powershell (Windows) eller bash (Linux) er forudsætningen for meget hurtig data processering. Ellers skal data hentes ind og ofte transformeres og dokumenteres før egentlig bearbejdning finder sted. Første skridt er ofte en reduktion af en række operationer, der sparer minutter til timer af tid, som kunne bruges andre steder. Et script før en rutineret indlæsning er oftest hurtigste måde at opdatere et dashboard, så alle de nødvendige informationer er up-to-date.
I journalistisk sammenhæng er opstillingen af statistik og adgang til tekniske datakilder i dag forsimplet i de offentlige gengivelser. De mest avancerede data i medierne er politiske surveys før valg eller gengivelser af resultater fra undersøgelser foretaget af organisationer og virksomheder, der udsender pressemeddelelser. Der er ellers mange muligheder for bedre historier. Nettet svømmer over med indrapporterings- og informationssider og kombinationen af kilder giver mulighed for en række spændende historier, når man kan håndtere materialet korrekt og/eller får en data kyndig statistisk konsulent som mig, til at kontrollere fortolkningerne. Lad os som et eksempel på en indrapporteringsside tage Oryx, der måske ikke er helt uden bias i sin tyrkisk pro-ukrainske fremlæggelse af informationer, men lader til at være en kilde til hvor mange kills tyrkiske Bayrakter står bag i den verserende krig i det østlige Ukraine.
Her kan vi tage de overordnede tal for som regneeksempel. Her den 14. april er 1583 stykker materiel enten ødelagt eller svært beskadiget, medens 1302 stykker materiel er efterladt eller erobret. I alt 1033 stykker materiel er erobret. Søger vi på siden med CRTL-F Bayrakter, får vi 53 hits, hvor Bayrakter nævnes 9 gange udenfor de russiske tab. Det giver 44 stykker tabt russisk materiel og et ukendt men ikke betydeligt antal døde russiske soldater. Lidt over 2% af de russiske tab skyldes altså Bayrakter, heraf ingen tanks, 4 pansrede kampkøretøjer, 1 infanterikøretøj, 1 kommunikationsstation, 1 styk ingeniørmateriel, 5 stykker ikke-selvkørende artilleri, 1 selvkørende raketkaster af typen Uragan (ikke Grad), hele 10 antiluftskyts missilsystemer samt 3 helikoptere heraf en kamphelikopter, 2 togsæt med brændstof samt 16 lastbiler. Det nævnes, at tre af de udlånte Bayrakter er taget ud af russerne. Der er jo til en historie i disse tal. Bayrakter ser et begrænset brug, og succesen med droner må skyldes brugen af mere almindelige kommercielle droner til målretning af artilleri og rekognoscering.
Ovenstående er almindelig informationssøgning baseret på læsning af en hjemmeside. En overvågning af hjemmesiden, der opdateres dagligt kunne herefter bestå i et bash og perl baseret skript for at finde de nødvendige tal i kilde filen på webserveren. Scriptet kan placeres på en Raspberry Pi, hvis ikke man har adgang til en server, og køre gentagne gange hver dag i baggrunden. Selvfølgelig kan der suppleres et dashboard på baggrund af opdateringer, der også viser udviklingen henover forskellige parametre.
Perl
use strict; use warnings; my $file = $ARGV[0] or die; my $filename = $ARGV[1] or die; open(FH, '<', $file) or die; open(FHW, '>', $filename) or die $!; sub main { my $total; my $destroyed; my $damaged; my $bayraktar_total=0; my $counting_total=0; my $bayraktar_tanks=0; my $counting_tanks=0; my $line; while(my $String = <FH>) { if($String =~ m/Russia - (.*)<br \/><\/span><\/h3><p style="text-align: left;">/) { $counting_total=1; $line = $1; $line =~ m/(.*), of which: destroyed:/; $total = $1; print "Total $total \n"; $line =~ m/, of which: destroyed: (.*), damaged: /; $destroyed = $1; print "Destroyed $destroyed \n"; $line =~ m/, damaged: (.*), abandoned: /; $damaged = $1; print "Damaged $damaged \n"; } if($counting_total==1) { my @count = $String =~ /[Bb]ayraktar/g; $bayraktar_total+= scalar @count if (scalar @count != 0); } $counting_total=0 if($String =~ m/Ukraine -(.*)<br \/><\/span><\/h3><div style="text-align: left;">/); $counting_tanks=1 if($String =~ m/<h3><span class="mw-headline" id="Pistols">Tanks/); if($counting_tanks==1){ my @count = $String =~ /[Bb]ayraktar/g; $bayraktar_tanks+= scalar @count if (scalar @count != 0); } $counting_tanks=0 if($String =~ m/<h3><span class="mw-headline" id="Pistols">Armoured Fighting Vehicles/); } print FHW localtime() . "," . $total . "," . $destroyed . "," . $damaged . "," . $bayraktar_total . "," . $bayraktar_tanks; print "Bayraktar total: $bayraktar_total \n"; print "Bayraktar tanks: $bayraktar_tanks \n"; close(FH); } main();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
use strict;
use warnings;
my $file = $ARGV[0] or die;
my $filename = $ARGV[1] or die;
open(FH, '<', $file) or die;
open(FHW, '>', $filename) or die $!;
sub main
{
my $total;
my $destroyed;
my $damaged;
my $bayraktar_total=0;
my $counting_total=0;
my $bayraktar_tanks=0;
my $counting_tanks=0;
my $line;
while(my $String = <FH>)
{
if($String =~ m/Russia - (.*)<br \/><\/span><\/h3><p style="text-align: left;">/)
{
$counting_total=1;
$line = $1;
$line =~ m/(.*), of which: destroyed:/;
$total = $1;
print "Total $total \n";
$line =~ m/, of which: destroyed: (.*), damaged: /;
$destroyed = $1;
print "Destroyed $destroyed \n";
$line =~ m/, damaged: (.*), abandoned: /;
$damaged = $1;
print "Damaged $damaged \n";
}
if($counting_total==1)
{
my @count = $String =~ /[Bb]ayraktar/g;
$bayraktar_total+= scalar @count if (scalar @count != 0);
}
$counting_total=0 if($String =~ m/Ukraine -(.*)<br \/><\/span><\/h3><div style="text-align: left;">/);
$counting_tanks=1 if($String =~ m/<h3><span class="mw-headline" id="Pistols">Tanks/);
if($counting_tanks==1){
my @count = $String =~ /[Bb]ayraktar/g;
$bayraktar_tanks+= scalar @count if (scalar @count != 0);
}
$counting_tanks=0 if($String =~ m/<h3><span class="mw-headline" id="Pistols">Armoured Fighting Vehicles/);
}
print FHW localtime() . "," . $total . "," . $destroyed . "," . $damaged . "," . $bayraktar_total . "," . $bayraktar_tanks;
print "Bayraktar total: $bayraktar_total \n";
print "Bayraktar tanks: $bayraktar_tanks \n";
close(FH);
}
main();
Her er resultat af en enkelt kørsel i bash shell
[gunnarhellmundlaier@localhost lost]$ wget https://www.oryxspioenkop.com/2022/02/attack-on-europe-documenting-equipment.html [gunnarhellmundlaier@localhost lost]$ cp attack-on-europe-documenting-equipment.html ./src/$(date '+%Y-%m-%d')_attack-on-europe-documenting-equipment.html [gunnarhellmundlaier@localhost lost]$ perl russian_casualties.pl ./src/2022-04-15_attack-on-europe-documenting-equipment.html ./data/test.txt Total 2897 Destroyed 1545 Damaged 44 Bayraktar total: 44 Bayraktar tank: 0
1
2
3
4
5
6
7
8
[gunnarhellmundlaier@localhost lost]$ wget https://www.oryxspioenkop.com/2022/02/attack-on-europe-documenting-equipment.html
[gunnarhellmundlaier@localhost lost]$ cp attack-on-europe-documenting-equipment.html ./src/$(date '+%Y-%m-%d')_attack-on-europe-documenting-equipment.html
[gunnarhellmundlaier@localhost lost]$ perl russian_casualties.pl ./src/2022-04-15_attack-on-europe-documenting-equipment.html ./data/test.txt
Total 2897
Destroyed 1545
Damaged 44
Bayraktar total: 44
Bayraktar tank: 0
Opdatering 20220707. Det er nu registreret, at Bayraktar har opdateret med missil, der er panserbrydende og kan ramme tanks.
Opdatering 20220907.
Observationen om destruktionen af en tank med Bayraktar er fjernet igen.
Comments