awk:固定長ファイルから複数の部分文字列を選択するには?

awk:固定長ファイルから複数の部分文字列を選択するには?

私は検索して検索しましたが、実際にこの質問に対する答えが見つかりませんでした。アイデアは、datファイルがあり、その中にいくつかのデータフィールドが必要であるということです。

サンプルデータ(test.dat)

50DI 20170510144200Mike   Tester       BL0004992000US
50ELI20170509145200Roy    Developer    BL0003400020MX

したがって、2番目のデータフィールドが位置3(DIまたはELI)から始まり、長さが3になるようにするには、次の手順を実行します。

awk '{print substr($0,3,3)}' test.dat

しかし、元のdatファイルから複数のデータフィールドを取得する方法がわかりません。私が思いついたことの中で最も良いのはこれです(以前のバージョンをコピーしながら編集されました)。

#!/bin/bash

for i in {1..1}; do
    a=$(awk '{print substr($0,0,2)}' test.txt)
    b=$(awk '{print substr($0,20,7)}' test.txt)
    echo $a, $b
done

結果は

50 50, Mike Roy

変える

50, Mike
50, Roy

この例は少し基本的ですが、アイデアは同じです。 awkを使って複数の部分文字列を取得するには? (免責事項:私はawkと結婚しているわけではありません。もっと良くなるように努力するだけです。他の解決策も高く評価されています!)

答え1

awk実際に固定幅が欲しいとし、GNUを使用すると、次のようになります。

awk -v FIELDWIDTHS='2 17 7' -v OFS=', ' '{ print $1, $3 }' test.dat

そしてbash

while read -r line; do
    printf '%s, %s\n' "${line:0:2}" "${line:19:7}"
done <test.dat

少し近代的sedです。

sed 's/^\(..\).\{17\}\(.\{7\}\).*/\1, \2/' test.dat

そしてperl

perl -lpe '$_ = join ", ", unpack "A2x17A7"' test.dat

上記の場合について以下を出力します。

50, Mike
50, Roy

答え2

どうですかcut

cut -c1-2,20-26 --output-delimiter ', ' test.dat
50, Mike
50, Roy

答え3

短いsed方法:

sed -En 's/^(.{2}).{17}(\S+).*/\1, \2/gp' test.dat

出力:

50, Mike
50, Roy

関連情報