从HTML文本文件中提取字符串并使用它来重命名文件

时间:2013-02-20 15:09:51

标签: linux shell sed awk grep

我有几个HTML文件,其中包含我想用于实际文件名的名称标记。 示例HTML文件:

    <div class="top">SomethingFile</div>
    <a href="../files/15d705df3.txt"/>

输出: 我希望SomethingFile标签是15d705df3.txt的名称

    15d705df3.txt --> SomethingFile.txt

我有大约800多个文本和HTML文件,这些格式与我想要重命名的格式相同。我一直在尝试使用awk,sed和grep。但不幸的是,我感到茫然,我不得不创建最初的两个变量,并使用这些变量来重命名该文件。

4 个答案:

答案 0 :(得分:2)

awk, sed, and grep are not the right tools for this task,我推荐你

xmllint --html --xpath '/Xpath/expression' file.html

使用Xpath expression

基本上

xmllint --html --xpath '//div[@class="top"]/text()' file.html

最后

for f in *.html *.txt; do
    filename=$(xmllint --html --xpath '//div[@class="top"]/text()' "$f")
    mv "$f" "$filename.txt"
done

答案 1 :(得分:0)

循环遍历文件,使用sed提取文件的新名称,然后重命名该文件。

for file in *
do
    name=$(sed -n 's|.*<div class="top">\(.*\)</div>|\1|p' "$file")
    mv "$file" "$name.txt"
done

答案 2 :(得分:0)

perl解析器html的帮助下使用HTML::TokeParser的一个解决方案:

#!/usr/bin/env perl

use warnings;
use strict;
use HTML::TokeParser;
use File::Spec;

my ($newfile, $currentfile);

## Give as arguments the html files to process, like *.html
for ( @ARGV ) { 
    my $p = HTML::TokeParser->new( $_ ) or die;

    ## Search a "div" tag with the attribute "class" to value "top".
    while ( my $info = $p->get_tag( 'div' ) ) { 
        if ( $info->[1]{class} eq 'top' ) { 

            $newfile = $p->get_text;

            ## Omit next two tokens until following "a" tag (</div>, space).
            $info = $p->get_token for 1 .. 3;

            ## If tag is a start 'a' tag, extract file name of the href attribute.
            if ( $info->[0] eq 'S' &&
                 $info->[1] eq 'a' ) { 
                $currentfile = ( File::Spec->splitpath( $info->[2]{href} ) )[2];
                $newfile .= join q||, (split /(\.)/, $currentfile)[-2 .. -1];
            }   
            last;
        }   
    }   

    ## Rename file.
    if ( $newfile && $currentfile ) { 
        printf STDERR qq|Renaming --> %s <-- to --> %s <--\n|, $currentfile, $newfile;
        rename $currentfile, $newfile;
    }   
    $newfile = $currentfile = undef;
}

像以下一样运行:

perl-5.14.2 script.pl *.html

我的测试中的一个结果应该类似于:

Renaming --> 15d705df3.txt <-- to --> SomethingFile1.txt <--
Renaming --> 15d705dg6.txt <-- to --> SomethingFile2.txt <--

答案 3 :(得分:0)

答案受@sputnick的启发,但使用 Xmlstarlet 代替xmllint

xml sel -T -t -o "mv " -f -o " " -t -v 'string(//div[@class="top"])' -o ".txt" -nl *.html 

给出:

mv t.html SomethingFile.txt
mv tt.html SomethingElse.txt

当你对自己的想法感到满意时。

xml sel -T -t -o "mv " -f -o " " -t -v 'string(//div[@class="top"])' -o ".txt" -nl *.html | sh

所有归功于@sputnick播种种子,让我能够背负。