106

次のようなファイルがあります。

    <table name="content_analyzer" primary-key="id">
      <type="global" />
    </table>
    <table name="content_analyzer2" primary-key="id">
      <type="global" />
    </table>
    <table name="content_analyzer_items" primary-key="id">
      <type="global" />
    </table>

に続く引用符内name=、つまり 、content_analyzercontent_analyzer2およびを抽出する必要がありcontent_analyzer_itemsます。

Linux ボックスでこれを行っているので、sed、perl、grep、または bash を使用したソリューションで問題ありません。

4

8 に答える 8

200

結果に含めずにコンテンツを一致させる必要があるため (一致する必要がありますがname=" 、目的の結果の一部ではありません)、何らかの形式のゼロ幅一致またはグループ キャプチャが必要です。これは、次のツールを使用して簡単に行うことができます。

パール

Perl では、n オプションを使用して行ごとにループし、一致する場合はキャプチャ グループの内容を出力できます。

perl -ne 'print "$1\n" if /name="(.*?)"/' filename

GNU grep

GNU grep など、grep の改良版を使用している場合は、 -Pオプションを使用できる場合があります。\Kこのオプションは、Perl のような正規表現を有効にし、省略形の後読みを使用できるようにします。一致位置がリセットされるため、それより前のものはゼロ幅です。

grep -Po 'name="\K.*?(?=")' filename

このo オプションにより、grep は行全体ではなく、一致したテキストのみを出力します。

Vim - テキストエディタ

もう 1 つの方法は、テキスト エディターを直接使用することです。Vim では、これを実現するためのさまざまな方法の 1 つとして、行を削除せず name=に行を削除し、結果の行からコンテンツを抽出します。

:v/.*name="\v([^"]+).*/d|%s//\1

標準 grep

何らかの理由でこれらのツールにアクセスできない場合は、標準の grep を使用して同様のことを行うことができます。ただし、見回さないと、後でクリーンアップが必要になります。

grep -o 'name="[^"]*"' filename

結果の保存に関する注意事項

上記のすべてのコマンドで、結果は に送信されstdoutます。追加してファイルにパイプすることで、いつでも保存できることを覚えておくことが重要です。

> result

コマンドの最後まで。

于 2011-02-22T17:21:05.513 に答える
5

正規表現は次のようになります。

.+name="([^"]+)"

次に、グループ化は\1になります

于 2011-02-22T16:39:26.443 に答える
5

Perl を使用している場合は、XML を解析するモジュールをダウンロードします: XML::SimpleXML::Twig、またはXML::LibXML。車輪を再発明しないでください。

于 2011-02-22T16:43:01.653 に答える
5

この目的には、正規表現ではなく HTML パーサーを使用する必要があります。を利用する Perl プログラムHTML::TreeBuilder:

プログラム

#!/usr/bin/env perl

use strict;
use warnings;

use HTML::TreeBuilder;

my $tree = HTML::TreeBuilder->new_from_file( \*DATA );
my @elements = $tree->look_down(
    sub { defined $_[0]->attr('name') }
);

for (@elements) {
    print $_->attr('name'), "\n";
}

__DATA__
<table name="content_analyzer" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
  <type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
  <type="global" />
</table>

出力

content_analyzer
content_analyzer2
content_analyzer_items
于 2011-02-22T17:12:29.427 に答える
2

これはそれを行うことができます:

perl -ne 'if(m/name="(.*?)"/){ print $1 . "\n"; }'
于 2011-02-22T16:39:07.423 に答える
2

HTML tidy & xmlstarlet を使用したソリューションは次のとおりです。

htmlstr='
<table name="content_analyzer" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer2" primary-key="id">
<type="global" />
</table>
<table name="content_analyzer_items" primary-key="id">
<type="global" />
</table>
'

echo "$htmlstr" | tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null |
sed '/type="global"/d' |
xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n
于 2011-03-16T17:49:36.630 に答える
1

おっと、sed コマンドはもちろん tidy コマンドの前になければなりません:

echo "$htmlstr" | 
sed '/type="global"/d' |
tidy -q -c -wrap 0 -numeric -asxml -utf8 --merge-divs yes --merge-spans yes 2>/dev/null |
xmlstarlet sel -N x="http://www.w3.org/1999/xhtml" -T -t -m "//x:table" -v '@name' -n
于 2011-03-16T17:59:18.213 に答える