awkとif文

awkとif文

awkを使用してファイルから印刷しようとしていますが、出力は空です。これはこれまで私のコードです

accountNum=$1
while read -r LINE || [[ -n $LINE ]] ; do
            awk -F',' '{ if($1==accountNum) { print $3.$2 } }' Accounts
done < Accounts

私もこれを試しました:

accountNum=$1
while read -r LINE || [[ -n $LINE ]] ; do
            echo $LINE  | awk -F',' '{ if($1==accountNum) { print $3.$2 } }' 
done < Accounts

入力ファイルは次のとおりです。

1,Doe,John
2,Rooney,Wayne
3,Smith,Will
4,Crow,Russel
5,Cruise,Tom

このファイルを実行するときに予想される出力は次のとおりです。

$./file.sh 3
Will Smith

ただし、次のメッセージが表示されます。

$./file.sh 3
$

つまり、何も印刷されないという意味です。 Cutのソリューションについて知っていますが、awkを使いたいです。

答え1

-v次のオプションを使用する必要がありますawk

awk -F',' -v accNum="$1" '$1 == accNum {print $3,$2}'

二重引用符を使用すると、$1シェルはすべての特殊文字(存在する場合)を処理します。

答え2

あなたは:

accountNum=$1
awk -F',' '{ if($1==accountNum) { print $3.$2 } }' Accounts

シェル変数はどのようにaccountNum入力されますかawk?そうではありません。awkその値を明示的に指定する必要があります。あなたはそれを使用することができます:

awk -F',' '{ if($1=='"$accountNum"') { print $3.$2 } }' Accounts

一重引用符を省略し、シェルがその変数の値をコマンドに置き換えてawkから、残りのコマンド文字列に一重引用符を再入力します。

より良い、少なくともより慣用的なスクリプトは次のとおりです。

#!/bin/sh
accountNum=$1
awk -F, '$1 == "'"$accountNum"'" { print $3,$2 }' Accounts

数字ではなくアカウント番号(代替変数を参照)を処理し、明示的なブロックの代わりにパターンブロックを使用しif{}以前のテストがtrueの場合はこのブロックが実行されます)、必要に応じて名前間のスペースを印刷します(,)。明示的な使用を好む場合は、既存のドアの内部にifテストを移動してください。if

実際の目標によっては、awk現在行っている作業に最も適していない可能性があります。スクリプトに引用符がある場合、$1上記の方法はまだ失敗します。シェルループが出力を何度も繰り返しても、役に立つことはありません。

答え3

あなたのスクリプトは実際に作業を行い、awkまったく必要ありません。

while IFS=, read -r num last first
    do  [ $((num==accountNum)) -eq 1 ] && 
        printf '%s.%s\n' "$first" "$last"
done < Accounts

これが個別に使用するよりも優れた効率的なソリューションであるとは言いませんが、awkループが必要な場合は、各行に対して別々のプロセスを実行するwhile...readよりもはるかに優れています。awkただ参考用だと思います。

答え4

#!/bin/bash

awk -v a="$1" -F ',' '$1 == a { print $3, $2 }' Accounts

-v a="$1"変数をスクリプトの最初のコマンドライン引数値に設定し、入力をコンマで区切るように指定します。最初の列が値と等しい場合、他の2つの列は逆の順序で印刷されます。awka-F ','a

awk最初の列を設定されていない変数と比較すると、出力には何も表示されませんaccountNum

項目の最初の列にゼロが含まれている場合は、その項目が印刷されます。これは、設定されていない変数の値がゼロとawk評価されるためです。

関連情報