特定の単語/記号に続く文字列を抽出します

特定の単語/記号に続く文字列を抽出します

入力ファイル input.txt に以下に示す 2 つの行があり、最初の行から claimStartDate を抽出し、2 行目から 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

これをすべて 1 回の実行で実行することもできます。

$ 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行を最初と最後の1つに切り捨てる
  • awkclaimStartDate最初の行にはを、ClaimEndDate2行目にはを印刷します。

答え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を抽出できます。claimStartDateProfessionalClaimProfessionalClaimProfessionalClaimclaimEndDate

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

これはまず、ProfessionalClaim別のノードが続く各ノードと一致しますProfessionalClaim

このような各ノードでは、属性の値が、区切り文字として 1 つのスペース文字を使用して、次のノードの属性claimStartDateの値と連結されます。claimEndDateProfessionalClaim

上記の例の文書では、次のように生成されます。

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

関連情報