
У меня есть две строки, как показано ниже, в моем входном файле input.txt, и мне нужно извлечь claimStartDate из первой строки и claimEndDate из второй строки.
<ProfessionalClaim paymentIndicator="P" claimProcessedDateTime="20180409120000102" claimEndDate="2018-04-02" claimStartDate="2018-04-02" sourceSystemId="abcd" claimActionCode="00">
<ProfessionalClaim paymentIndicator="P" claimProcessedDateTime="20180430120000281" claimEndDate="2018-04-17" claimStartDate="2018-04-17" sourceSystemId="abcd" claimActionCode="00">
rm input.txt
awk '/<ProfessionalClaim/' test.xml | head -1 > input.txt
awk '/<ProfessionalClaim/' test.xml | tail -1 >> input.txt
awk '{match($0, "claimStartDate=\"([^\"]+)\"", start); print start[1]} \
{match($0, "claimEndDate=\"([^\"]+)\"", end); print end[1]}' input.txt
решение1
$ awk '/F_LINE/ {match($0, "claimStartDate=\"([^\"]+)\"", start); print start[1]} \
/L_LINE/ {match($0, "claimEndDate=\"([^\"]+)\"", end); print end[1]}' input.txt
2018-04-02
2018-04-17
ИЗМЕНИТЬ в связи с вашей новой информацией:
$ awk 'NR==1 {match($0, "claimStartDate=\"([^\"]+)\"", start); print start[1]} \
NR==2 {match($0, "claimEndDate=\"([^\"]+)\"", end); print end[1]}' input.txt
2018-04-02
2018-04-17
Вы также можете сделать все это за один проход:
$ grep "<ProfessionalClaim" text.xml \
| sed -n '1p;$p' \
| $ awk 'NR==1 {match($0, "claimStartDate=\"([^\"]+)\"", start); print start[1]} \
NR==2 {match($0, "claimEndDate=\"([^\"]+)\"", end); print end[1]}'
grep
найти все строки с<ProfessionalClaim
вtext.xml
sed
обрезать строки до первой и последней толькоawk
напечатаетclaimStartDate
для первой строки иClaimEndDate
для второй строки
решение2
Предположим, что имеется некий входной XML-документ, подобный следующему:
<?xml version="1.0"?>
<root>
<ProfessionalClaim paymentIndicator="P" claimProcessedDateTime="20180409120000102" claimEndDate="2018-04-02" claimStartDate="2018-04-02" sourceSystemId="abcd" claimActionCode="00"/>
<ProfessionalClaim paymentIndicator="P" claimProcessedDateTime="20180430120000281" claimEndDate="2018-04-17" claimStartDate="2018-04-17" sourceSystemId="abcd" claimActionCode="00"/>
<ProfessionalClaim paymentIndicator="P" claimProcessedDateTime="20180430120000281" claimEndDate="2018-04-18" claimStartDate="2018-04-18" sourceSystemId="abcd" claimActionCode="00"/>
<ProfessionalClaim paymentIndicator="P" claimProcessedDateTime="20180430120000281" claimEndDate="2018-04-19" claimStartDate="2018-04-19" sourceSystemId="abcd" claimActionCode="00"/>
</root>
... мы можем использовать xmlstarlet
для извлечения claimStartDate
значения атрибута из каждого ProfessionalClaim
узла, за которым следует другой ProfessionalClaim
узел, вместе со значением атрибута этого следующего ProfessionalClaim
узла :claimEndDate
xmlstarlet select --template \
--match '//ProfessionalClaim[following-sibling::ProfessionalClaim/@claimEndDate]' \
--value-of 'concat(@claimStartDate, " ", following-sibling::ProfessionalClaim/@claimEndDate)' \
-nl input.txt
Сначала сопоставляется каждый ProfessionalClaim
узел, за которым следует другой ProfessionalClaim
узел.
Для каждого такого узла значение атрибута claimStartDate
объединяется со значением атрибута claimEndDate
следующего ProfessionalClaim
узла, используя в качестве разделителя один пробел.
Учитывая мой пример документа выше, это сгенерирует
2018-04-02 2018-04-17
2018-04-17 2018-04-18
2018-04-18 2018-04-19