簡體   English   中英

使用Unix Shell腳本進行文件解析

[英]File parsing using Unix Shell Scripting

我正在嘗試進行一些轉換,但遇到了困難。 這里是問題描述。

以下是管道定界文件。 我已經屏蔽了數據!

AccountancyNumber|AccountancyNumberExtra|Amount|ApprovedBy|BranchCurrency|BranchGuid|BranchId|BranchName|CalculatedCurrency|CalculatedCurrencyAmount|CalculatedCurrencyVatAmount|ControllerBy|Country|Currency|CustomFieldEnabled|CustomFieldGuid|CustomFieldName|CustomFieldRequired|CustomFieldValue|Date|DateApproved|DateControlled|Email|EnterpriseNumber|ExpenseAccountGuid|ExpenseAccountName|ExpenseAccountStatus|ExpenseGuid|ExpenseReason|ExpenseStatus|ExternalId|GroupGuid|GroupId|GroupName|IBAN|Image|IsInvoice|MatchStatus|Merchant|MerchantEnterpriseNumber|Note|OwnerShip|PaymentMethod|PaymentMethodGuid|PaymentMethodName|ProjectGuid|ProjectId|ProjectName|Reimbursable|TravellerId|UserGUID|VatAmount|VatPercentage|XpdReference|VatCode|FileName|CreateTstamp
61470003||30.00|null|EUR|168fcea9-17d4-45a1-8b6f-bfb249cdbea6|BEL|BEL|USD,INR,EUR|35.20,2420.11,30.00|null,null,null|null|BE|EUR|true|0d4b767b-0988-47e8-9144-05e607169284|careertitle|false|FE|2018-07-24T00:00:00|null|null|abc_def@xyz.com||c32f03c6-31df-4fd8-8cc2-1c5f3a580aad|Meals - In Office|true|781d10d2-2f3b-43bc-866e-a653fefacbbe||Approved|70926|40ac7117-c7e2-42ea-b34f-96330c9380b6|BEL-FSP-Users|BEL-FSP-Users|||false|None|in office meal #1|||Personal|Cash|1ee44666-f4c7-44b3-acd3-8ecd7127480a|Cash|2cb4ccb7-634d-4386-af43-b4572ec72098|00AA06|00AA06|true||6c5a835f-5152-46db-923a-3ebd08c7dad3|null|null|XPD012245802||1820711.xml|2018-08-07 05:42:10.46

在此文件中,我們有CalculatedCurrency字段,其中有多個用逗號分隔的值。 該文件還具有字段CalculatedCurrencyAmount ,該字段也具有多個用逗號分隔的值。 但是我只需要從CalculatedCurrency字段(屬於BranchCurrency (文件中的另一個字段)中選擇該貨幣值,當然BranchCurrency為該貨幣選擇對應的CalculatedCurrencyAmount

所需輸出:-

AccountancyNumber | AccountancyNumberExtra |金額|都批准了| BranchCurrency | BranchGuid | BranchId | BRANCHNAME | CalculatedCurrency | CalculatedCurrencyAmount | CalculatedCurrencyVatAmount | ControllerBy |國家|貨幣| CustomFieldEnabled | CustomFieldGuid | CustomFieldName | CustomFieldRequired | CustomFieldValue |日期| DateApproved | DateControlled |郵箱| EnterpriseNumber | ExpenseAccountGuid | ExpenseAccountName | ExpenseAccountStatus | ExpenseGuid | ExpenseReason | ExpenseStatus |外部編號| GroupGuid |的GroupId |組名| IBAN |圖片| IsInvoice | MatchStatus |商家| MerchantEnterpriseNumber |注意|所有權|付款方法| PaymentMethodGuid | PaymentMethodName | ProjectGuid |專案編號|項目名|可償還| TravellerId | UserGUID | VatAmount | VatPercentage | XpdReference | VatCode |文件名| CreateTstamp | ActualCurrency | ActualAmount 61470003 || 30.00 | null | EUR | 168fcea9-17d4-45a1-8b6f-bfb249cdbea6 | BEL | BEL | USD,INR,EUR | 35.20,2420.11,30.00 | null,null,null | null | null | BE | EUR |真| 0d4b767b-0988-47e8-9144-05e607169284 | careertitle |虛假| FE | 2018-07-24T00:00:00 |空|空| abc_def@xyz.com || c32f03c6-31df-4fd8-8cc2-1c5f3a580aad |餐-在辦公室中| true | 781d10d2-2f3b-43bc-866e-a653fefacbbe ||已批准| 70926 | 40ac7117-c7e2-42ea-b34f-96330c9380b6 | BEL-FSP-用戶| BEL-FSP-用戶|||假|無|無辦公餐#1 |||個人|現金| 1ee44666-f4c7-44b3-acd3-8ecd7127480a |現金| 2cb4ccb7-634d-4386-af43-b4572ec72098 | 00AA06 | 00AA06 | true || 6c5a835f-5152-46db-923a-3ebd08c7d null | null | XPD012245802 || 1820711.xml | 2018-08-07 05:42:10.46 | EUR | 30.00

請幫忙。

Snaplogic Python腳本

from com.snaplogic.scripting.language import ScriptHook
from com.snaplogic.scripting.language.ScriptHook import *
import csv

class TransformScript(ScriptHook):
    def __init__(self, input, output, error, log):
        self.input = input
        self.output = output
        self.error = error
        self.log = log

    def execute(self):
        self.log.info("Executing Transform script")

        while self.input.hasNext():
            data = self.input.next()
            branch_currency = data['BranchCurrency']
            calc_currency = data['CalculatedCurrency'].split(',')
            calc_currency_amount = data['CalculatedCurrencyAmount'].split(',')

            result = None
        for i, name in enumerate(calc_currency):
            result = calc_currency_amount[i] if name == branch_currency else result
            data["CalculatedCurrencyAmount"] = result
            result1 = calc_currency[i] if name == branch_currency else result
            data["CalculatedCurrency"] = result1



            try:
                data["mathTryCatch"] = data["counter2"].longValue() + 33
                self.output.write(data)
            except Exception as e:
                data["errorMessage"] = e.message
                self.error.write(data)






        self.log.info("Finished executing the Transform script") 
hook = TransformScript(input, output, error, log)

使用awk:

awk 'BEGIN{FS=OFS="|"}
     NR==1{print $0,"ActualCurrency","ActualAmount";next}
     {n=split($9,a,",");split($10,b,",");for(i=1;i<=n;i++) if(a[i]==$5) print $0,$5,b[i]}' file

BEGIN{FS=OFS="|"}設置輸入和輸出定界符為|

NR==1語句通過添加2個字符串來處理標題。

第9和第10個字段基於,分隔符進行拆分,並且在數組ab中設置值。

for循環正在嘗試查找與第5個字段相對應a數組的值。 如果找到,則打印b的相應值。

在某些數組上使用bash:

arr_find() {
        echo $(( $(printf "%s\0" "${@:2}" | grep -Fnxz "$1" | cut -d: -f1) - 1 ))
}
IFS='|' read -r -a headers
while IFS='|' read -r "${headers[@]}"; do
        IFS=',' read -r -a CalculatedCurrency <<<"$CalculatedCurrency"
        IFS=',' read -r -a CalculatedCurrencyAmount <<<"$CalculatedCurrencyAmount"

        idx=$(arr_find "$BranchCurrency" "${CalculatedCurrency[@]}")
        echo "BranchCurrency is $BranchCurrency. Hence CalculatedCurrency will be ${CalculatedCurrency[$idx]} and CalculatedCurrencyAmount will have to be ${CalculatedCurrencyAmount[$idx]}."

done

首先,我閱讀了所有標題名稱。 然后將所有值讀入標頭。 然后正確讀取CalculatedCurrency *,使它們之間用','分隔。 然后,我發現等於CalculatedCurrency中的BranchCurrency的元素編號。 有了元素索引和數組,我就可以打印輸出了。

我知道,op要求使用unix shell,但是作為一種替代選擇,我顯示了一些使用python進行編碼的代碼。 (顯然,此代碼也可以進行重大改進。)例如,最大的優勢是可讀性,您可以通過名稱來尋址數據。 或者說,代碼比使用awk等人的代碼更具可讀性。

將數據保存在data.psv ,將以下腳本寫入文件main.py 我已經使用python3 python2對其進行了測試。 兩者都可以。 使用python main.py運行腳本。

更新:我已經擴展了腳本以解析所有行。 在示例數據中,我已經在第一行中將BranchCurrency設置為EUR,在第二行中將USD設置為虛擬測試。

檔案:main.py

import csv

def parse_line(row):
  branch_currency = row['BranchCurrency']
  calc_currency = row['CalculatedCurrency'].split(',')
  calc_currency_amount = row['CalculatedCurrencyAmount'].split(',')

  result = None
  for i, name in enumerate(calc_currency):
    result = calc_currency_amount[i] if name == branch_currency else result

  return result


def main():
  with open('data.psv') as f:
    reader = csv.DictReader(f, delimiter='|')
    for row in reader:
      print(parse_line(row))


if __name__ == '__main__':
  main()

示例數據:

[:~] $ cat data.psv 
AccountancyNumber|AccountancyNumberExtra|Amount|ApprovedBy|BranchCurrency|BranchGuid|BranchId|BranchName|CalculatedCurrency|CalculatedCurrencyAmount|CalculatedCurrencyVatAmount|ControllerBy|Country|Currency|CustomFieldEnabled|CustomFieldGuid|CustomFieldName|CustomFieldRequired|CustomFieldValue|Date|DateApproved|DateControlled|Email|EnterpriseNumber|ExpenseAccountGuid|ExpenseAccountName|ExpenseAccountStatus|ExpenseGuid|ExpenseReason|ExpenseStatus|ExternalId|GroupGuid|GroupId|GroupName|IBAN|Image|IsInvoice|MatchStatus|Merchant|MerchantEnterpriseNumber|Note|OwnerShip|PaymentMethod|PaymentMethodGuid|PaymentMethodName|ProjectGuid|ProjectId|ProjectName|Reimbursable|TravellerId|UserGUID|VatAmount|VatPercentage|XpdReference|VatCode|FileName|CreateTstamp
61470003||35.00|null|EUR|168fcea9-17d4-45a1-8b6f-bfb249cdbea6|BEL|BEL|USD,INR,EUR|35.20,2420.11,30.00|null,null,null|null|BE|EUR|true|0d4b767b-0988-47e8-9144-05e607169284|careertitle|false|FE|2018-07-24T00:00:00|null|null|abc_def@xyz.com||c32f03c6-31df-4fd8-8cc2-1c5f3a580aad|Meals - In Office|true|781d10d2-2f3b-43bc-866e-a653fefacbbe||Approved|70926|40ac7117-c7e2-42ea-b34f-96330c9380b6|BEL-FSP-Users|BEL-FSP-Users|||false|None|in office meal #1|||Personal|Cash|1ee44666-f4c7-44b3-acd3-8ecd7127480a|Cash|2cb4ccb7-634d-4386-af43-b4572ec72098|00AA06|00AA06|true||6c5a835f-5152-46db-923a-3ebd08c7dad3|null|null|XPD012245802||1820711.xml|2018-08-07 05:42:10.46
61470003||35.00|null|USD|168fcea9-17d4-45a1-8b6f-bfb249cdbea6|BEL|BEL|USD,INR,EUR|35.20,2420.11,30.00|null,null,null|null|BE|EUR|true|0d4b767b-0988-47e8-9144-05e607169284|careertitle|false|FE|2018-07-24T00:00:00|null|null|abc_def@xyz.com||c32f03c6-31df-4fd8-8cc2-1c5f3a580aad|Meals - In Office|true|781d10d2-2f3b-43bc-866e-a653fefacbbe||Approved|70926|40ac7117-c7e2-42ea-b34f-96330c9380b6|BEL-FSP-Users|BEL-FSP-Users|||false|None|in office meal #1|||Personal|Cash|1ee44666-f4c7-44b3-acd3-8ecd7127480a|Cash|2cb4ccb7-634d-4386-af43-b4572ec72098|00AA06|00AA06|true||6c5a835f-5152-46db-923a-3ebd08c7dad3|null|null|XPD012245802||1820711.xml|2018-08-07 05:42:10.46

示例運行:

[:~] $ python main.py 
30.00
35.20

您根本不需要在這里使用腳本捕捉。 始終為轉換編寫腳本會影響性能,並且完全破壞了IPaaS工具的目的。 映射器就足夠了。

我針對此問題創建了以下測試管道。

在此處輸入圖片說明

我將這個問題中提供的數據保存在文件中,並將其保存在SnapLogic中以進行測試。 在管道中,我使用CSV解析器對其進行了解析。

在此處輸入圖片說明

以下是解析結果。

在此處輸入圖片說明

然后,我使用了一個映射器來進行所需的轉換。

在此處輸入圖片說明

以下是獲取實際金額的表達式。

$CalculatedCurrency.split(',').indexOf($BranchCurrency) >= 0 ? $CalculatedCurrencyAmount.split(',')[$CalculatedCurrency.split(',').indexOf($BranchCurrency)] : null

以下是結果。

在此處輸入圖片說明

避免針對可使用映射器解決的問題編寫腳本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM