3

Awk を使用して処理したいレガシー システムのデータ ファイルがいくつかあります。各ファイルは、レコードのリストで構成されています。いくつかの異なるレコード タイプがあり、各レコード タイプには異なる固定幅フィールドのセットがあります (フィールド区切り文字はありません)。レコードの最初の 2 文字はタイプを示しており、これからどのフィールドが続くかがわかります。ファイルは次のようになります。

AAField1Field2LongerField3
BBField4Field5Field6VeryVeryLongField7Field8
CCField99

Gawk を使用してFIELDWIDTHSを設定できますが、それはファイル全体に適用されます (レコードごとにこれを設定する方法がない場合を除きます)。または、FS を "" に設定してファイルを 1 文字で処理することもできます。時間ですが、それは少し面倒です。

Awk を使用してそのようなファイルからフィールドを抽出する良い方法はありますか?

編集:はい、Perl(または他のもの)を使用できます。ただし、Awkでそれを行う賢明な方法があるかどうかを知りたいと思っています。

4

6 に答える 6

8

うまくいけば、これがあなたを正しい方向に導くでしょう。複数行のレコードが「CC」タイプの行で終了することが保証されていると仮定すると、単純な if-then ロジックを使用してテキスト ファイルを前処理できます。1 つの行にフィールド 1、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 
于 2009-09-08T13:23:42.870 に答える
5

おそらく2つのパスを使用できます:

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
于 2009-09-08T12:53:53.470 に答える
4

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関数を使用して各フィールドを位置ごとに抽出する必要があると思います。そのため、レコード タイプごとに 1 行として取得したものは、各レコード タイプのフィールドごとに 1 行のようになります。 、および後続の印刷。

unpackPerl とその機能を使用したほうがよいと思いますがawk、冗長ではありますが、それも処理できます。

于 2009-09-08T12:21:12.380 に答える
3

Perl を使用して、行の最初の 2 文字に基づいて展開テンプレートを選択していただけますか?

于 2009-09-08T11:48:25.987 に答える
0

2つのスクリプトはどうですか?たとえば、最初のスクリプトは最初の文字に基づいてフィールド セパレータを挿入し、2 番目のスクリプトはそれを処理する必要がありますか?

または、まず最初に、入力に基づいて行を変数に分割する AWK スクリプトでいくつかの関数を定義します。

于 2009-09-08T12:19:56.660 に答える
0

perl や ruby​​ などのフル機能のスクリプト言語を使用することをお勧めします。

于 2009-09-08T11:37:21.670 に答える