簡體   English   中英

使用Awk處理每個記錄具有不同固定寬度字段的文件

[英]Using Awk to process a file where each record has different fixed-width fields

我有遺留系統的一些數據文件,我想用Awk處理。 每個文件都包含一個記錄列表。 有幾種不同的記錄類型,每種記錄類型都有一組不同的固定寬度字段(沒有字段分隔符)。 記錄的前兩個字符表示類型,然后您可以知道應該遵循哪些字段。 文件可能如下所示:

AAField1Field2LongerField3
BBField4Field5Field6VeryVeryLongField7Field8
CCField99

使用Gawk我可以設置FIELDWIDTHS ,但這適用於整個文件(除非我在某個記錄的基礎上缺少某種方式設置它),或者我可以將FS設置為“”並處理文件中的一個字符一段時間,但這有點麻煩。

有沒有一種使用Awk從這樣的文件中提取字段的好方法?

編輯 :是的,我可以使用Perl(或其他)。 我仍然很想知道是否有一種合理的方法可以用Awk做到這一點。

希望這會引導您朝着正確的方向前進。 假設您的多行記錄保證由“CC”類型行終止,您可以使用簡單的if-then邏輯預處理文本文件。 我假設您需要在一行上使用fields1,5和7,並且需要一個示例awk腳本。

BEGIN {
        field1=""
        field5=""
        field7=""
}
{
    record_type = substr($0,1,2)
    if (record_type == "AA")
    {
        field1=substr($0,3,6)
    }
    else if (record_type == "BB")
    {
        field5=substr($0,9,6)
        field7=substr($0,21,18)
    }
    else if (record_type == "CC")
    {
        print field1"|"field5"|"field7
    }
}

創建一個名為program.awk的awk腳本文件,並將該代碼彈入其中。 使用以下命令執行腳本:

awk -f program.awk < my_multi_line_file.txt 

你可以使用兩個通行證:

1step.awk

/^AA/{printf "2 6 6 12"    }
/^BB/{printf "2 6 6 6 18 6"}
/^CC/{printf "2 8"         }
{printf "\n%s\n", $0}

2step.awk

NR%2 == 1 {FIELDWIDTHS=$0}
NR%2 == 0 {print $2}

接着

awk -f 1step.awk sample  | awk -f 2step.awk

您可能需要抑制(或至少忽略) awk的內置字段分隔代碼,並使用以下行的程序:

awk '/^AA/ { manually process record AA out of $0 }
     /^BB/ { manually process record BB out of $0 }
     /^CC/ { manually process record CC out of $0 }' file ...

手動處理會有點繁瑣 - 我想你需要使用substr函數按位置提取每個字段,所以我每個記錄類型的一行更像是每個記錄中每行一行類型,加上后續打印。

我認為使用Perl及其unpack功能可能會更好,但awk也可以處理它,盡管很冗長。

你可以使用Perl,然后根據該行的前兩個字符選擇一個解包模板嗎?

更好地使用一些全功能的腳本語言,如perl或ruby。

兩個腳本怎么樣? 例如,第一個腳本根據第一個字符插入字段分隔符,然后第二個腳本應該處理它?

或者首先在AWK腳本中定義一些函數,它根據輸入將行拆分為變量 - 我會這樣做,以便重新使用。

暫無
暫無

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

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