フィールド 3、4、5、8 を切り取る必要があるテキスト ファイルがあります。
219 432 4567 Harrison Joel M 4540 Accountant 09-12-1985
219 433 4587 Mitchell Barbara C 4541 Admin Asst 12-14-1995
219 433 3589 Olson Timothy H 4544 Supervisor 06-30-1983
219 433 4591 Moore Sarah H 4500 Dept Manager 08-01-1978
219 431 4527 Polk John S 4520 Accountant 09-22-1998
219 432 4567 Harrison Joel M 4540 Accountant 09-12-1985
219 432 1557 Harrison James M 4544 Supervisor 01-07-2000
デフォルトの区切り文字はタブなので、フィールドを抽出するコマンドは次のようになります。
cut -f 3,4,5,8 filename
問題は、出力が元のファイルの内容と同じであることです。ここで何が起こっているのでしょうか? なぜこれが機能しないのでしょうか?
答え1
列間のスペースはすべてタブではないため、cut
必要な操作を実行できません。代わりに を使用することをお勧めします。これは、次のようなデータの列を解析する場合awk
よりも柔軟性があります。cut
$ awk '{print $3,$4,$5,$8}' data.txt
例
$ awk '{print $3,$4,$5,$8}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
次のコマンドを使用して出力にスペースを入れることもできますcolumn
。
$ awk '{print $3,$4,$5,$8}' data.txt |column -t
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
awk
とだけを使用してすべてを行うこともできますprintf
。
$ awk '{printf "%s\t%-20s\t%s\n",$3,$4" "$5,$8}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
カット再考
上記の方法は問題なく機能しますが、特定の列の値内にスペースがある行は処理されません。たとえば、「Dept Manager」の行は Dept だけに切り詰められます。
データが図示のような構造であることが保証される場合は、cut
区切り文字で分割する代わりに、文字の実際の位置を使用して表示することができます。
例
これにより、ファイルからテキストが切り取られdata.txt
、位置 9 から 13、14 から 35 などにある内容が印刷されます。
$ cut -c 9-13,14-35,43-58 data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin Asst
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept Manager
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
awk 再考
Awk は、区切り文字ではなく位置に基づいてテキストを取り出すこともできます。ただし、より冗長になりますが、完全を期すために、以下にその方法を示します。
$ awk '{
printf "%s\t%-20s\t%s\n",substr($0,9,5),substr($0,14,22),substr($0,43,16)
}' data.txt
4567 Harrison Joel Accountant
4587 Mitchell Barbara Admin Asst
3589 Olson Timothy Supervisor
4591 Moore Sarah Dept Manager
4527 Polk John Accountant
4567 Harrison Joel Accountant
1557 Harrison James Supervisor
awk フィールド幅
GNU のバリアントを使用している場合は、awk
変数を使用してFIELDWIDTHS
各フィールドの静的サイズを指定できます。このsubstr
方法は、メソッドにアクセスできる場合、はるかに簡潔になります。また、通常は個別のフィールドとして解析されるフィールドを効果的に結合することもできます。
$ awk 'BEGIN { FIELDWIDTHS="4 4 5 24 5 16 11" }{ print $3,$4,$5,$6 }' data.txt
4567 Harrison Joel M 4540 Accountant
4587 Mitchell Barbara C 4541 Admin Asst
3589 Olson Timothy H 4544 Supervisor
4591 Moore Sarah H 4500 Dept Manager
4527 Polk John S 4520 Accountant
4567 Harrison Joel M 4540 Accountant
1557 Harrison James M 4544 Supervisor
答え2
私の推測では、それらはタブではないと思います。それらがタブではないと思う理由は、ファイルをコピーして貼り付け、フィールドを手動で集計すると、正常に機能するように見えるからです。フィールドと値を再集計したくない場合は、cut -f 3,4,5,8 filename
そうしたほうがよいでしょう。cat filename | awk '{print $3, $4, $5, $8}'