web-dev-qa-db-ja.com

awk / cutを使用してスペースのある列データを取得する方法

以下の形式のデータがあります。

 16 SQL*Plus                            vilconv1                  dox-conv2
 16 TOAD background query session       Disha                     WORKGROUP\AD

列ごとにデータを取得したいので、以下のコマンドを使用しています

awk '{print $1,$2}' 

しかし、列2にはスペースがあるため、出力の下に私を与えています:

16 SQL*Plus      
  16 TOAD

私が欲しいのは:

16 SQL*Plus  
   16 TOAD background query session   
5
user73680

列がタブで区切られている場合は、フィールド区切り文字としてタブ文字を指定できます。これにより、スペースを個別の列として扱うawkのデフォルトの動作が回避されます。

cat <data file> | awk -F"\t" '{print $1, $2}'

root@ubuntu32:/tmp# cat testtext | awk -F"\t" '{print $1, $2}'
16 SQL*Plus
16 TOAD background query session
2
ASG

これを行う1つの方法は、unexpandを使用することです。その説明とexpandユーティリティを見つけることができます here

  • unexpandユーティリティは、ファイルまたは標準入力を標準出力にコピーし、各行の先頭の<blank>文字を最大数の<tab>文字に変換し、その後に同じ列の位置を埋めるために必要な最小数の<space>文字を続けます。翻訳された<blank>文字で埋められます。デフォルトでは、タブストップは8列ごとに設定されます。各<backspace>は出力にコピーされ、タブ計算の列位置カウントが減少します。カウントは1未満の値にデクリメントされません。

あなたはおそらく-aスイッチを望んでいるでしょう。

  • -a-各行の先頭の<blank>文字の変換に加えて、タブストップの直前にある2つ以上の<blank>文字のシーケンスをすべて、同じ列を埋めるために必要な<tab>文字の最大数とそれに続く<space>文字の最小数に変換します。翻訳された<blank>文字によって最初に埋められた位置。

代わりに、多くのスペースを順番にタブに変換するシンプルなユーティリティです。そのようにしてあなたはできる...

unexpand -a <<\IN | cut -f1
 16 SQL*Plus                            vilconv1                  dox-conv2
 16 TOAD background query session       Disha                     WORKGROUP\AD
IN

...印刷する...

 16 SQL*Plus
 16 TOAD background query session

ここではcutを使用していますが、必要に応じてawkなどを使用できます。ほぼ間違いなくすでにインストールされており、使用方法は非常に簡単で、非常に高速であるため、この方法をお勧めします。それは区切り文字を交換することによってスペースの問題を解決します-そしてそれは非常に簡単です。

私はヒアドキュメントもそれがどのように機能するかを示すためだけに使用しますが、おそらく代わりにしたいでしょう...

unexpand -a <infile | filter program
1
mikeserv

@Costasの提案が気に入り、別のオプションは次のとおりです。

gawk '
  {
    f1=substr($0,2,2)
    f2=substr($0,4,36)
    gsub(/ *$/, "", f2)
    print f1 " " f2
  }
'
1
Eran Ben-Natan