0

「 」タグ.xmlを検索する必要があるファイルがあります。<reviseddate>ファイル内に複数回存在する可能性があります。<reviseddate>その場合、「 」タグを「 」に置き換える<reviseddate1>必要があります。これにはシェルスクリプトが必要です

テキストのサンプルは次のとおりです。

Manuscript received <receiveddate>June 7, 2005</receiveddate>; revised             
<reviseddate> February 4, 2006 </reviseddate>, <reviseddate> August 14, 2006 </reviseddate>,
and <reviseddate> October 7, 2006 </reviseddate>. This work was supported by the 
<supported><agency-name>California Department of Transportation through the California  
Center for Innovative Transportation and the California Partners for Advanced Highway 
and Transit Program</agency-name><grant-grp/></supported>. The contents of this paper 
reflect the views of the authors and do not necessarily indicate acceptance by the 
sponsors. The Associate Editor for this paper was M. M. Sokoloski.</affnote-para>

出力は次のようになります

Manuscript received <receiveddate> June 7, 2005 <receiveddate>; revised             
<reviseddate1> February 4, 2006 </reviseddate1>, <reviseddate2> August 14, 2006 </reviseddate2>,        
and <reviseddate3> October 7, 2006 </reviseddate3>. This work was supported by the 
<supported><agency-name>California Department of Transportation through the California  
Center for Innovative Transportation and the California Partners for Advanced Highway 
and Transit Program</agency-name><grant-grp/></supported>. The contents of this paper 
reflect the views of the authors and do not necessarily indicate acceptance by the 
sponsors. The Associate Editor for this paper was M. M. Sokoloski.</affnote-para>

私はもう試した:

for i in $c do 
   sed -e "s/<reviseddate>/<reviseddate$i>/g" $path/$input_file > $path/input_new.xml
   cp $path/input_new.xml $path/$input_file 
   rm -f input_new.xml 
done
4

1 に答える 1

0

このような Perl スクリプトを使用して作業を行います。

#!/usr/bin/env perl
use strict;
use warnings;

my $i = 1;
while (<>)
{
    while (m%<reviseddate>([^<]+)</reviseddate>%)
    {
        s%<reviseddate>([^<]*)</reviseddate>%<reviseddate$i>$1</reviseddate$i>%;
        $i++;
    }
    print;
}

行ごとに、番号のないタグごと<reviseddate>に、タグを適切な番号のタグに置き換えます。

出力例:

Manuscript received <receiveddate>June 7, 2005</receiveddate>; revised             
<reviseddate1> February 4, 2006 </reviseddate1>, <reviseddate2> August 14, 2006 </reviseddate2>,
and <reviseddate3> October 7, 2006 </reviseddate3>. This work was supported by the 
<supported><agency-name>California Department of Transportation through the California  
Center for Innovative Transportation and the California Partners for Advanced Highway 
and Transit Program</agency-name><grant-grp/></supported>. The contents of this paper 
reflect the views of the authors and do not necessarily indicate acceptance by the 
sponsors. The Associate Editor for this paper was M. M. Sokoloski.</affnote-para>

これを調整して、ある行の開始タグと次の行の終了タグなど、別のシナリオに対処できます。それが必要になるまで、それについて大騒ぎしても意味がありません。正規表現の使用は芸術です。考えられるすべてのシナリオで、当面の必要性と回復力のバランスを取る必要があります。


Perl は明らかに「シェル」ではありません (シェルsedです) ため、すべてのエントリを見つけて変更するのに十分な頻度でファイルを処理するように手配できます。

tmp=$(mktemp ./revise.XXXXXXXXXXXX)
trap "rm -f $tmp; exit 1" 0 1 2 3 13 15

i=1
while grep -s '<reviseddate>' filename
do
    sed "1,/<reviseddate>/ s%<reviseddate>\([^<]*\)</reviseddate>%<reviseddate$i>\1</reviseddate$i>%" filename > $tmp
    mv $tmp filename
    i=$(($i+1))
done

rm -f $tmp # Should be a no-op
trap 0

これにより、ファイルが繰り返し更新されます。この部分は、最初のタグのみが更新1,/<reviseddata>されることを保証します(コマンドには何もありません。これは重要です)。トラップ コードは、一時ファイルが残らないようにします。<reviseddate>gs%%%

これはサンプルデータで機能し、同じ出力が得られました。小さなファイルの場合は問題ありません。数ギガバイトのファイルを管理している場合は、ファイルを 1 回処理するため、Perl の方が適しています。

于 2013-03-08T08:33:46.363 に答える