Extrahieren Sie eine Zeichenfolge, der ein bestimmtes Wort/Symbol folgt

Extrahieren Sie eine Zeichenfolge, der ein bestimmtes Wort/Symbol folgt

Ich habe zwei Zeilen, wie unten gezeigt, in meiner Eingabedatei input.txt und ich muss claimStartDate aus der ersten Zeile und claimEndDate aus der zweiten Zeile extrahieren.

<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

Antwort1

$ 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

BEARBEITEN aufgrund Ihrer neuen Informationen:

$ 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

Sie können dies auch alles in einem Durchgang erledigen:

$ 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]}'
  • grepfinde alle Zeilen mit <ProfessionalClaimintext.xml
  • sedkürze die Zeilen auf die erste und die letzte
  • awkdruckt claimStartDatefür die erste Zeile und ClaimEndDatefür die zweite Zeile

Antwort2

Nehmen wir an, es handelt sich um ein XML-Eingabedokument wie das folgende:

<?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>

... können wir verwenden, xmlstarletum den claimStartDateAttributwert aus jedem ProfessionalClaimKnoten zu extrahieren, dem ein weiterer ProfessionalClaimKnoten folgt, zusammen mit dem Attributwert des nächsten ProfessionalClaimKnotens :claimEndDate

xmlstarlet select --template \
    --match '//ProfessionalClaim[following-sibling::ProfessionalClaim/@claimEndDate]' \
    --value-of 'concat(@claimStartDate, " ", following-sibling::ProfessionalClaim/@claimEndDate)' \
    -nl input.txt

Dadurch wird zunächst jeder ProfessionalClaimKnoten abgeglichen, auf den ein weiterer Knoten folgt ProfessionalClaim.

Für jeden solchen Knoten wird der Wert des claimStartDateAttributs mit dem Wert des claimEndDateAttributs des folgenden ProfessionalClaimKnotens verkettet, wobei ein einzelnes Leerzeichen als Trennzeichen dient.

In meinem obigen Beispieldokument würde dies Folgendes ergeben:

2018-04-02 2018-04-17
2018-04-17 2018-04-18
2018-04-18 2018-04-19

verwandte Informationen