Ищете правильный шаблон в файлах в папке?(Может быть, с Perl или с некоторыми Apis на Java или что-нибудь еще) - PullRequest
0 голосов
/ 24 марта 2011

У меня есть папка с именем v3. В этой папке находятся файлы jsp, также в папке v3 есть несколько папок, и в этой папке также есть файлы jsp.

В моих папках jsp есть ссылки вроде:

<link rel="stylesheet" href="/static/css/main.css" type="text/css" />
<link rel="stylesheet" type="text/css" href="/css<s:text name="scripts"/>/general_styles.css">
<link rel="stylesheet" type="text/css" href="/v3/css<s:text name="scripts"/>/something.css" >

и сценарии:

<script language="javascript" type="text/javascript" src="/static/scripts/jquery-1.4.2.min.js"></script>
<script type="text/javascript" src="/scripts<s:text name="scripts"/>/prototype-1.6.0.2.js"></script>
<script language="javascript" type="text/javascript" src="/scripts<s:text name="scripts"/>/${a.name}/<s:text name="genericJs"/>"></script>

Для ссылок:

href должен начинаться с /static/, например, это действительно:

<link rel="stylesheet" href="/static/css/main.css" type="text/css" />

Для скриптов:

src должен начинаться также с /static/, например, это действительно:

<script language="javascript" type="text/javascript" src="/static/scripts/jquery-1.4.2.min.js"></script>

Что я хочу сделать, чтобы определить, какие файлы имеют определения not valid.

РЕДАКТИРОВАТЬ: Действительный - недействительным является понятие для системы моей компании. Мы перемещаем наши папки css и js в другую, и они будут в папке, и имя этой папки v3.

Программа будет работать так:

  • jsp файлы находятся в папке v3. Я буду запускать эту программу из любого места, и она проверит все jsp-файлы в этой папке (я определю полный путь к этой папке v3 в написанной программе).

  • Он найдет все строки, которые начинаются с <link и <script.

  • Если это <link, он найдет href="

  • Если это <script, он найдет src="

  • После того, как он найдет один из них, он проверит, начинается ли он с /static/ или нет.

  • Если запускается, то все в порядке, но если нет, то записывает имя файла в выходной / текстовый файл или что-то еще.

Ответы [ 3 ]

1 голос
/ 24 марта 2011

Вы можете посмотреть на ack, это замена на основе Perl для grep и должна быть в состоянии делать то, что вы хотите.

По правде говоря, вы не хотите выполнять сопоставление с шаблоном [xht] ml, вы хотите использовать парсер.Сценарий Perl, использующий HTML::TokeParser, может найти все теги с определенными атрибутами.

Вот быстрый макет, хотя вам может потребоваться более полезный вывод:

#!/usr/bin/perl

use strict;

use warnings;

use File::chdir;
use Cwd 'abs_path';

use HTML::TokeParser;

my @paths = @ARGV;
my @files;

foreach my $path (@paths) {
  local $CWD = $path;
  opendir( my $dh, $CWD);
  push @files, map { abs_path($_) } grep {/\.jsp$/} readdir $dh;
}

foreach my $file (@files) {
  my $parser = HTML::TokeParser->new($file);

  while (my $tag = $parser->get_tag("link", "script")) {

    if ($tag->[0] eq "link" and exists $tag->[1]{'href'}) {
      print "$file\n" unless $tag->[1]{'href'} =~ m#^/static/#;

    } elsif ($tag->[0] eq "script" and exists $tag->[1]{'src'}) {
      print "$file\n" unless $tag->[1]{'src'} =~ m#^/static/#;
    }

  }  

}
1 голос
/ 24 марта 2011

Используйте HTML :: TreeBuilder (и, следовательно, HTML :: Element ) и look_down, чтобы найти ваши вещи.

use strict;
use warnings;
use 5.012;

use HTML::TreeBuilder;

my @filelist = @ARGV; ### or some other method ofc.

for my $file (@filelist) {
  my $tree = HTML::TreeBuilder->new_from_file($file)->elementify;
  for my $e ( $tree->look_down( '_tag' => 'link',
                                sub { !($_[0]->attr('href') =~ |^/static/|) }
                              ) 
            ) {
    say "$file: ", $e->as_HTML;
  }
}

Также довольно просто модифицировать ваш HTML с помощью того же скрипта (то есть, конкатенировать '/ static /' в начале плохих атрибутов - $e->attr('href') = '/static/' . $e->attr('href')) и выплюнуть его обратно с помощью HTML :: Приборка с HTML::Tidy->new->clean($tree->as_HTML).

Edit: Ваш вопрос о списке файлов, назначение ARGV для списка файлов было сделано просто потому, что это было касательно вопроса. См. Как найти в каталоге все файлы .XXX и получить их список в Perl? , например. Я бы использовал File :: Find :

use File::Find;
my @rootdirs = @ARGV or die "Please pass all root directories to search as arguments!";
my @filelist = find( sub { /\.jsp$/ or return; }, @rootdirs );

Это будет проходить через ваши начальные каталоги (передаваемые по аргументу - вы также можете назначить их непосредственно @rootdirs, если хотите) и предоставить вам все файлы .jsp в них как элементы в @ filelist.

0 голосов
/ 24 марта 2011

Что-то вроде этого поможет вам:

public static void main(String[] args) throws IOException {
    Iterator<File> files = FileUtils.iterateFiles(new File("/path/to/v3"), new String[]{"jsp"}, true);
    while (files.hasNext()) {
        File jsp =  files.next();
        List<String> list = FileUtils.readLines(jsp);
        for (String line : list) {
            if(line.startsWith("<link") || line.startsWith("<script")) {
                if(!line.contains("/static")) {
                    throw new RuntimeException("invalid file found: " + jsp.getAbsolutePath());
                }
            }
        }
    }
}

Отредактировано, чтобы содержать изменения, обсуждаемые в комментариях

...