
私のファイルには識別できないデータが含まれています。次のように教えてください。
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
.
.</Record></ns0:collection>
N個のファイルをマージして1つのファイルを作成する必要があります。したがって、次のことを行う必要があります。
</ns0:collection>
最初のファイルから閉じるタグを削除するだけです。- 次の(n-1)個のファイルの
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0">
合計を削除する</ns0:collection>
- 最後のファイルのみを削除し、
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0">
すべてマージする必要があります。
コマンドを使用して最初のファイルを処理しようとしましたが、sed
結果が出ませんでした。 "merged.xml"は空でした。
sed '/<\/ns0:collection>/d' $file1 > merged.xml
どんな提案がありますか?
答え1
useのみを指定していないsed
ため、アクセス権がある場合xml_grep
(参照コマンドラインから複数のXMLファイルをマージする、2番目の答え)、これはあなたに多くの負担を与え、次の簡単なマージ操作を単一のコマンドで実行できるため、これをお勧めします。
xml_grep --cond Record --wrap "ns0:collection" --descr 'xmlns:ns0="http://namespace/Service/1.0"' --encoding "UTF-8" *.xml
テストファイル:
テスト.xml
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namespace/Service/1.0""><Record>
Test
</Record></ns0:collection>
テスト1.xml
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namespace/Service/1.0"><Record>
Test 1<a>a</a><b c="c">d</b>
</Record></ns0:collection>
結果
<?xml version="1.0" encoding="UTF-8" ?>
<ns0:collection xmlns:ns0="http://namespace/Service/1.0">
<Record>
Test 1<a>a</a><b c="c">d</b></Record><Record>
Test
</Record>
</ns0:collection>
XMLファイルを扱うときに構造を台無しにする可能性がsed
非常に高く、誤った形式のXML文書になりやすいので、XML認識ツールを使用することをお勧めします!
答え2
sed
XML処理に適していないusingを使用し、代わりにパーサーを使用することをお勧めします。
また、ここにXYの問題があることを示唆しています。タグを削除するのではなく、XMLファイルをマージすることです。
個人的に - 私はperl
以下が好きですXML::Twig
:
#!/usr/bin/env perl
use strict;
use warnings;
#load the parser
use XML::Twig;
#get our file list - we use the "first" file as the basis.
#can use sort on this list if desired.
my ( $first_file, @other_files ) = glob ( 'C://tmp//xmltest/*.xml' );
#Our 'parent' document.
my $doc = XML::Twig -> new -> parsefile ( $first_file );
foreach my $file ( @other_files ) {
my $mergedoc = XML::Twig -> new -> parsefile ( $file );
#//Record means any <Record> node anywhere in the tree.
foreach my $record ( $mergedoc -> get_xpath ( '//Record' ) ) {
$record -> cut;
#paste it into our parent doc, as the last node.
$record -> paste ( after => $doc -> root -> last_child );
}
}
#set output formatting (optional)
$doc -> set_pretty_print ('indented_a');
#print to STDOUT.
$doc -> print;
#write to output file too
open ( my $output, '>', 'combined.xml' ) or die $!;
print {$output} $doc -> sprint;
close ( $output );
これは、意図的にターゲットXMLから要素を抽出し、Record
文書間でマージします。しかし、これはxpath
非常に強力で正規表現と同じXMLのような柔軟なアプローチですが、正規表現はそうではありませんが、コンテキストを認識するので、より良いです。
答え3
解決策:
最初のファイルから閉じるタグのみを削除する必要があります。回避策:
sed -i.bak -e 's/<\/ns0:collection>/ /' -e 's/<\/Record>/ /' n0
次の(n-1)ファイルの合計を削除します
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection xmlns:ns0="http://namspace/Service/1.0">
。</ns0:collection>
sed -i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' -e 's/<\/R.*>.*>/ /' n1
さまざまなファイル名に対して以下を実行します。
find . -type f -name "n[1-3]" -exec sed i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' -e 's/<\/R.*>.*>/ /' {} \;
最後のファイルのみを削除し、すべてマージする必要があります。
sed i.bak -e 's/<?xml version=1.0 encoding=UTF-8 ?>.*<ns0:collection/ /' -e 's/xmlns.*/ /' ne
最後に参加してください:
cat n0 n[1-3] ne > joined
n0
、、、n1
およびn2
。ファイルを使用しましたn3
。ne
各コンテンツに次のテキストを追加しました。
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
hello from nigeria
</Record></ns0:collection>
生成されたファイルはjoined
次のとおりです。
<?xml version="1.0" encoding="UTF-8" ?><ns0:collection
xmlns:ns0="http://namspace/Service/1.0"><Record>
hello from nigeria
hello from nigeria
hello from nigeria
hello from nigeria
hello from nigeria
</Record></ns0:collection>
メモ:
最初の質問では、
</Record></ns0:collection>
両方だけでなく</ns0:collection>
。</Record>
すべてのファイルに対して1つのコマンドを実行できるように、ここのファイル名を変更する必要があります
n[1-3]
。ここでは、最も適切な名前を選択しました。まず、テストを実行して結果を確認してください。、ここでは自動的にバックアップを作成するために使用します
i.bak
。sed