Extraer cadena seguida de una palabra/símbolo específico

Extraer cadena seguida de una palabra/símbolo específico

Tengo dos líneas como se muestra a continuación en mi archivo de entrada input.txt y necesito extraer ClaimStartDate de la primera línea y ClaimEndDate de la segunda línea.

<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

Respuesta1

$ 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

EDITAR debido a su nueva información:

$ 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

También puedes hacer todo esto en una sola ejecución:

$ 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]}'
  • grepencontrar todas las líneas con <ProfessionalClaimentext.xml
  • sedtruncar las líneas al primer y último onyl
  • awkimprimirá el claimStartDatepara la primera línea y ClaimEndDatepara la segunda línea

Respuesta2

Suponiendo algún documento de entrada XML como el siguiente:

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

... podemos usar xmlstarletpara extraer el claimStartDatevalor del atributo de cada ProfessionalClaimnodo al que ProfessionalClaimle sigue otro nodo, junto con el valor del atributo ProfessionalClaimdel siguiente nodo :claimEndDate

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

Este primero coincide con cada ProfessionalClaimnodo seguido de otro ProfessionalClaimnodo.

Para cada uno de estos nodos, el valor del claimStartDateatributo se concatena con el valor del claimEndDateatributo del siguiente ProfessionalClaimnodo, con un solo carácter de espacio como delimitador.

Dado mi documento de ejemplo anterior, esto generaría

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

información relacionada