Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
executable file 137 lines (131 sloc) 5.65 KB
#!/usr/bin/perl
#
# ds-collect, v1.0.1, CLI
# Copyright © 2016-2017 Dmitry Sokolov
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# Более общая вариация скрипта ds-collectcolors, для поиска не только цветов.
# Скрипт ищет в указанных файлах или каталогах значения по указанным регулярным
# выражениям, для каждого найденного запоминает количество его упоминаний,
# позицию, оригинальную нотацию и сохраняет всё это в текстовый файл и шаблон
# замены для ds-convert, схлопывая только до уникальных значений и сортируя их
# по количеству упоминаний от большего к меньшему.
# Подробнее: http://sokolov.website/programs/ds-utils/ds-collect
#
# Зависимости: perl
# Рекомендуется: enca
#
# ds-collect [-r] [-e кодировка] [-o файл_найденного] [-t файл_шаблона]
# [-m регвыр] [файл(-ы)] [путь(-и)]
#
# -r — от recursive — Анализировать рекурсивно (по умолчанию — нет).
# -e — от encoding — Кодировка читаемых файлов
# (по умолчанию — * — автоопределение с помощью enca).
# -o — от output — Создаваемый текстовый файл с найденными значениями
# (по умолчанию — ./collected.txt).
# -t — от template — Создаваемый файл шаблона замены с найденными значениями
# для последующей их замены скриптом ds-convert
# (по умолчанию — ./templated.cot).
# -m — от mask — Регулярное выражение имени файла, без пути
# (по умолчанию соответствует любому имени).
# файл(-ы)/путь(-и) — По умолчанию — . — текущий каталог.
#
# Пример: ds-collect -r -e CP1251 -o /tmp/found.txt -t /tmp/change.txt \
# -m '.*\.(?:css|html)' /var/www ~/onemore.css
#
# Dmitry Sokolov <dmitry@sokolov.website>
use strict;
use warnings;
use utf8;
use open qw/:encoding(UTF-8) :std/;
use POSIX;
use File::Spec;
use File::Find;
use Getopt::Std;
use Encode;
my (@result, @dirs, $opte, %opts, $mask);
my ($inner, $output, $template) = (0, "", "");
my @sample = (
'text\-transform\:\s*([^;]*);',
);
sub collect_in_file {
my $file = shift;
my $source = undef;
if($opts{e} eq '*') {$opte = `enca -r '$file'` || "UTF-8"; chomp $opte;}
else {$opte = $opts{e};}
open(IN, "<:encoding($opte)", $file)
or print "Can’t open $file: $!\n" and return;
while($_ = <IN>) {$source .= $_;}
close(IN);
for(my $i = 0; $i < scalar @sample; $i++) {
my $s = $sample[$i];
$s =~ s/\\(\d+)/'\\'.($1+1)/ge;
while($source =~ m/($s)/g) {
for(my $y = 0; $y <= scalar @result; $y++) {
if(scalar @result == 0
|| ($y == $#result && $1 ne $result[$y]->{orig})) {
my $val = $2 ? $2 : $1;
$result[++$#result] = {
orig => $1,
conv => $val,
pths => [$file],
wght => 1
};
last;
}
if(scalar @result != 0 && $1 eq $result[$y]->{orig}) {
$result[$y]->{wght}++;
$result[$y]->{pths}->[++$#{$result[$y]->{pths}}] = $file
unless $file ~~ @{$result[$y]->{pths}};
last;
}
}
}
}
}
sub wanted {
if(!$inner) {$inner = 1; return;}
$File::Find::prune = 1 if !$File::Find::prune && !(exists $opts{r});
if(-f && -s && -T && $_ =~ $mask) {&collect_in_file($File::Find::name);}
}
getopts('re:o:t:m:', \%opts);
$opts{e} = '*' unless exists $opts{e};
$opts{o} = './collected.txt' unless exists $opts{o};
$opts{t} = './templated.cot' unless exists $opts{t};
$mask = exists $opts{m} ? qr/$opts{m}/ : qr/.+/;
@dirs = @ARGV ? @ARGV : ('.');
foreach(@dirs) {
my $fullname = decode("UTF-8", File::Spec->rel2abs($_));
if(-f && -s && -T && $_ =~ $mask) {&collect_in_file($fullname);}
else {$inner = 0; find(\&wanted, $fullname);}
}
foreach(sort {$b->{wght} <=> $a->{wght}} @result) {
$output .=
$_->{conv} . " " x (35 - length $_->{conv}) . "\t\t" .
"weight " . $_->{wght} . " " x (5 - length $_->{wght}) .
"of original " . $_->{orig} . " " x (28 - length $_->{orig}) .
"at '" . join("', '", @{$_->{pths}}) . "'" .
"\n";
$template .=
$_->{orig} . " " x (25 - length $_->{orig}) . "\t" .
$_->{orig} . " " x (25 - length $_->{orig}) . "\t" .
"'" . join("', '", @{$_->{pths}}) . "'" .
"\n";
}
if(open(OUT, ">:encoding(UTF-8)", $opts{o})) {print OUT $output; close(OUT);}
else {print "Can’t create $opts{o}: $!\n";}
if(open(OUT, ">:encoding(UTF-8)", $opts{t})) {print OUT $template; close(OUT);}
else {print "Can’t create $opts{t}: $!\n";}
exit 0;