Para Um com POSIX sed
e head
utilitários e um arquivo regular in
:
{ sed -ne'/^<ric id="AUG03250639E=YBAU">$/q;p'
head -n21 >/dev/null
cat
} <in >out
Bom dia,
Sou novo no UNIX, portanto, estou procurando fazer algo que possa ser feito no VB, mas não tenho a experiência necessária no UNIX.
Eu tenho uma especificação xml em um compartilhamento que exige exclusão e atualizações regulares à medida que novos códigos RIC reuters ficam on-line. Dois itens para alcançar:
Remover uma entrada do RIC
Eu acho que isso pode funcionar:
sed –e '/<ric id="AUG03250639E=YBAU">/,+21d' a.xml >a.xml
B. Adicionar uma nova entrada de RIC
</source>
<ricid="AAAAA=YBAU"
to <ricid="BBBBB=YBAU"
Como posso fazer isso?
Esta é a última seção do arquivo. Observe que o fim dos blocos ricos (que eu quero manipular) é quando as strings a seguir aparecem . . .
<ric id="AUG03250639E=YBAU">
<securities>
<security>
<issueid>178117</issueid>
<quote-type>YIELD</quote-type>
<complex-logic>
<calculations>
<yield-type>
<type>BID_YIELD</type>
<calculation name="AB" field="RT_YIELD_1" />
</yield-type>
<yield-type>
<type>OFFER_YIELD</type>
<calculation name="AB" field="SEC_YLD_1" />
</yield-type>
</calculations>
</complex-logic>
<derived-type name="PRICE" baseValue="100.0" />
</security>
</securities>
</ric>
<ric id="AUG03250640E=YBAU">
<securities>
<security>
<issueid>178117</issueid>
<quote-type>YIELD</quote-type>
<complex-logic>
<calculations>
<yield-type>
<type>BID_YIELD</type>
<calculation name="AB" field="RT_YIELD_1" />
</yield-type>
<yield-type>
<type>OFFER_YIELD</type>
<calculation name="AB" field="SEC_YLD_1" />
</yield-type>
</calculations>
</complex-logic>
<derived-type name="PRICE" baseValue="100.0" />
</security>
</securities>
</ric>
</rics>
<topics>
<topic>
<id>default</id>
<type>rmds</type>
<value>IDN_SELECTFEED.ANY.%s.NaE</value>
</topic>
</topics>
</source>
<transformers>
<!-- Name of transformer -->
<transformer></transformer>
</transformers>
<processors>
<!-- Enricher to add additional fields from source query result while
publishing -->
<processor></processor>
</processors>
<endpoints>
<!-- Order of post processor is important. First topic, then mapper -->
<endpoint id="rmds" topic="FI.ANY.%s.YBAU" multicast="true">
<postprocessor>reuters-topic-builder</postprocessor>
<postprocessor>reuters-message-mapper</postprocessor>
<!-- <multitopic id="solace" topic="LN/FI/IP/APS/SSHEET/YIELD/BATS_%s"
/> -->
<multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/SSHEET/BATS_%s" />
<multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/YIELDBROKER/BATS_%s" />
</endpoint>
</endpoints>
<other-properties>
<!-- common formatting of price/yield -->
<property name="formattor-1">(math:pow(INPUT/100+1,0.5)-1)*200</property>
<property name="handle_negative_values">false</property>
<property name="handle_negative_values_output">0.001</property>
</other-properties>
</specification>
Portanto, para A. Remova uma entrada RIC onde desejo remover AUG03250640E = YBAU, o arquivo mostrará:
<ric id="AUG03250639E=YBAU">
<securities>
<security>
<issueid>178117</issueid>
<quote-type>YIELD</quote-type>
<complex-logic>
<calculations>
<yield-type>
<type>BID_YIELD</type>
<calculation name="AB" field="RT_YIELD_1" />
</yield-type>
<yield-type>
<type>OFFER_YIELD</type>
<calculation name="AB" field="SEC_YLD_1" />
</yield-type>
</calculations>
</complex-logic>
<derived-type name="PRICE" baseValue="100.0" />
</security>
</securities>
</ric>
</rics>
<topics>
<topic>
<id>default</id>
<type>rmds</type>
<value>IDN_SELECTFEED.ANY.%s.NaE</value>
</topic>
</topics>
</source>
<transformers>
<!-- Name of transformer -->
<transformer></transformer>
</transformers>
<processors>
<!-- Enricher to add additional fields from source query result while
publishing -->
<processor></processor>
</processors>
<endpoints>
<!-- Order of post processor is important. First topic, then mapper -->
<endpoint id="rmds" topic="FI.ANY.%s.YBAU" multicast="true">
<postprocessor>reuters-topic-builder</postprocessor>
<postprocessor>reuters-message-mapper</postprocessor>
<!-- <multitopic id="solace" topic="LN/FI/IP/APS/SSHEET/YIELD/BATS_%s"
/> -->
<multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/SSHEET/BATS_%s" />
<multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/YIELDBROKER/BATS_%s" />
</endpoint>
</endpoints>
<other-properties>
<!-- common formatting of price/yield -->
<property name="formattor-1">(math:pow(INPUT/100+1,0.5)-1)*200</property>
<property name="handle_negative_values">false</property>
<property name="handle_negative_values_output">0.001</property>
</other-properties>
</specification>
Para B. Adicione uma nova entrada RIC assumindo que eu quero adicionar o novo ric AUG03250641E = YBAU, o arquivo mostrará:
<ric id="AUG03250639E=YBAU">
<securities>
<security>
<issueid>178117</issueid>
<quote-type>YIELD</quote-type>
<complex-logic>
<calculations>
<yield-type>
<type>BID_YIELD</type>
<calculation name="AB" field="RT_YIELD_1" />
</yield-type>
<yield-type>
<type>OFFER_YIELD</type>
<calculation name="AB" field="SEC_YLD_1" />
</yield-type>
</calculations>
</complex-logic>
<derived-type name="PRICE" baseValue="100.0" />
</security>
</securities>
</ric>
<ric id="AUG03250640E=YBAU">
<securities>
<security>
<issueid>178117</issueid>
<quote-type>YIELD</quote-type>
<complex-logic>
<calculations>
<yield-type>
<type>BID_YIELD</type>
<calculation name="AB" field="RT_YIELD_1" />
</yield-type>
<yield-type>
<type>OFFER_YIELD</type>
<calculation name="AB" field="SEC_YLD_1" />
</yield-type>
</calculations>
</complex-logic>
<derived-type name="PRICE" baseValue="100.0" />
</security>
</securities>
</ric>
<ric id="AUG03250641E=YBAU">
<securities>
<security>
<issueid>178117</issueid>
<quote-type>YIELD</quote-type>
<complex-logic>
<calculations>
<yield-type>
<type>BID_YIELD</type>
<calculation name="AB" field="RT_YIELD_1" />
</yield-type>
<yield-type>
<type>OFFER_YIELD</type>
<calculation name="AB" field="SEC_YLD_1" />
</yield-type>
</calculations>
</complex-logic>
<derived-type name="PRICE" baseValue="100.0" />
</security>
</securities>
</ric>
</rics>
<topics>
<topic>
<id>default</id>
<type>rmds</type>
<value>IDN_SELECTFEED.ANY.%s.NaE</value>
</topic>
</topics>
</source>
<transformers>
<!-- Name of transformer -->
<transformer></transformer>
</transformers>
<processors>
<!-- Enricher to add additional fields from source query result while
publishing -->
<processor></processor>
</processors>
<endpoints>
<!-- Order of post processor is important. First topic, then mapper -->
<endpoint id="rmds" topic="FI.ANY.%s.YBAU" multicast="true">
<postprocessor>reuters-topic-builder</postprocessor>
<postprocessor>reuters-message-mapper</postprocessor>
<!-- <multitopic id="solace" topic="LN/FI/IP/APS/SSHEET/YIELD/BATS_%s"
/> -->
<multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/SSHEET/BATS_%s" />
<multitopic id="solace-credit" topic="LN/FI/EP/CREDITBPS/YIELDBROKER/BATS_%s" />
</endpoint>
</endpoints>
<other-properties>
<!-- common formatting of price/yield -->
<property name="formattor-1">(math:pow(INPUT/100+1,0.5)-1)*200</property>
<property name="handle_negative_values">false</property>
<property name="handle_negative_values_output">0.001</property>
</other-properties>
</specification>
Para Um com POSIX sed
e head
utilitários e um arquivo regular in
:
{ sed -ne'/^<ric id="AUG03250639E=YBAU">$/q;p'
head -n21 >/dev/null
cat
} <in >out
Exceto pelo fato de que analisar e / ou manipular xml com expressões regulares é equivocado na melhor das hipóteses (embora coisas simples como essa funcionem se você tiver cuidado), você quase acertou:
Usando o GNU sed:
sed –i -e '/<ric id="AUG03250639E=YBAU">/,+21d' a.xml
Se o seu sed não suportar a opção -i
( --in-place
), você poderá fazê-lo com um arquivo temporário (que é como o sed o faz nos bastidores):
TF=$(mktemp)
sed -e '/<ric id="AUG03250639E=YBAU">/,+21d' a.xml > "$TF" && mv "$TF" a.xml
Você não pode ler de um arquivo e redirecionar a saída para ele no shell como você tentou - a primeira coisa que o shell fará é sobrescrever o arquivo para que fique vazio, e isso acontece antes do script sed ser executado.
Para tarefas de análise XML mais complexas, use um analisador XML como xmlstarlet
em scripts shell ou uma das muitas bibliotecas de análise XML para perl ou python (ou quase qualquer outra linguagem que você possa imaginar)
Não use expressões regulares para analisar XML. Está sujo - propenso a quebrar e cria um código frágil. Há um monte de coisas que podem te enganar trivialmente, como contagens de linha - é perfeitamente válido em XML para formatar um elemento:
<calculation name="AB" field="SEC_YLD_1" />
Ou:
<calculation
field="SEC_YLD_1"
name="AB"
/>
E uma variedade de outras opções - todas semanticamente idênticas, mas ... não combinam com a mesma expressão regular.
Para sua amostra, isso é incrivelmente fácil se você usar um analisador. perl
tem XML::Twig
, que pode fazer isso com facilidade:
Excluir:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> parsefile ( 'your_file.xml' );
$_ -> delete for $twig -> get_xpath('//ric[@id="AUG03250639E=YBAU"]');
$twig -> set_pretty_print('indented');
$twig -> print;
Nota - exclui duplicatas se existir alguma.
Agora, crie um novo - parece que você está tentando copiar e corrigir - assim:
#!/usr/bin/env perl
use strict;
use warnings;
use XML::Twig;
my $twig = XML::Twig -> parsefile ( 'your_file.xml' );
#find one to copy - this will just get the first 'ric' element.
my $ric_to_copy = $twig -> get_xpath('//ric',0);
#copy it
my $new_ric = $ric_to_copy -> copy;
#alter the new one
$new_ric -> set_att('id', 'BBBBB=YBAU' );
#paste it
$new_ric -> paste ( 'last_child', $ric_to_copy->parent);
$twig -> set_pretty_print('indented');
$twig -> print;
Agora, isso lê e imprime em STDOUT - você pode imprimir em um arquivo específico:
my ( $output, '>', 'new.xml') or die $!;
print {$output} $twig -> sprint;
close ( $output );
Tags text-processing sed xml