awkコマンドでエラーが発生しました

awkコマンドでエラーが発生しました

入力する:

123456.00|aswani|india|ap
23456.00|rani|us|tel
233|ramu|londan|vih

出力:

aswani|ap
rani|tel
ramu|vih

次のコマンドを使用してこの出力を取得しようとしています。

awk '{FS="|";OFS="|"}{print $2,$4}'

しかし、私が得た結果は次のとおりです。

|
rani|tel
ramu|vih

コマンドはライン 2 で実行されますが、ライン 1 では実行されません。最初の行で出力しようとしています。

答え1

「BEGIN」ブロック内に最初のブロック(FSおよびOFS設定)を入れる必要があります。

awk 'BEGIN {FS="|";OFS="|"} {print $2,$4}'

「BEGIN」ブロックを実行します今後テキストの最初の行が処理されました。代わりに実行される別のブロックがあります。すべてただし、最初の行の場合、フィールドがすでに分割されているため、FS設定が遅すぎます。

別の方法は、awkコマンドラインオプションを使用してFSを設定することですが、まだOFSを処理する必要があります。

awk -F '|' '{OFS="|"; print $2,$4}'

または:

awk -F '|' -v OFS='|' '{print $2,$4}'

修正する:@Kusalanandaが指摘したように、awkいくつかの実装(BSD awkなど)は、FSがリセットされるとフィールドを再分割するため、「BEGIN」ブロックに設定する必要はありません。 GNU awk(通常はLinuxディストリビューションにあるもの)ではこれは起こらないので、行を分割する前にFSを設定する必要があります。

答え2

〜のようにフィルブランドンが指摘した。GNU awk(および)を正しく設定するmawk必要があります。FS今後最初の行を読みます。それ以外の場合は、デフォルトのフィールド区切り文字(一連のスペース)に従って行が分割されます。あなたのコードセットFS 後ろに各行が読み込まれるため、ファイルの最初の行を処理すると誤った値が発生します。

OpenBSDはawk(少なくとも)異なる動作をし、フィールドにアクセスすると現在のレコードを分割するように見えますが、以前はそうではありません。これは、あなたのコードが実際にOpenBSDシステムで実行できることを意味します。

追加の処理なしでファイルから列セットを抽出するためにこのコマンドを追加します。このcutコマンドも便利です。

$ cut -d '|' -f 2,4 <file
aswani|ap
rani|tel
ramu|vih

関連情報