ifステートメントのあるawk


8

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
$

それは何も印刷されていません。カットの解決策は知っていますが、awkを使用したいと思います。

回答:


8

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

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

$1二重引用符で、シェルはあなたのために(ある場合)、そのすべての特殊文字を処理します。


3

あなたが持っている:

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引用符が含まれている場合、上記はまだ失敗します。あなたが持っていたシェルループは何も有用ではありませんでしたが、それは何回も出力を繰り返したでしょう。


whileループを外すべきだと言ってるの?:)
gkmohit 2014

少なくとも例では、それはあなたを助けるために何もしていません。
Michael Homer

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各行の個別のプロセスに勝ります。参考までに。


すべての行に対して1つのawkだけでなく、そのawkはシェル自体が読み取るすべての行についてファイル全体を再度読み取ります。O(n ^ 2)アルゴリズムを取得する方法。
Paul_Pedant

1
#!/bin/bash

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

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

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

最初の列に0(ゼロ)が含まれるエントリがあった場合、そのエントリは出力されます。これは、の未設定変数の値がawkゼロに評価されるためです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.