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つの列は逆の順序で印刷されます。awk
a
-F ','
a
awk
最初の列を設定されていない変数と比較すると、出力には何も表示されませんaccountNum
。
項目の最初の列にゼロが含まれている場合は、その項目が印刷されます。これは、設定されていない変数の値がゼロとawk
評価されるためです。