[英]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.