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を使用したいと思います。
awk
の-v
オプションを使用する必要があります:
awk -F',' -v accNum="$1" '$1 == accNum {print $3,$2}'
二重引用符で囲まれた$1
を使用すると、シェルはすべての特殊文字(ある場合)を処理します。
あなたが持っている:
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
には引用符が含まれています。あなたが持っていたシェルループは何も有用なことをしていませんでしたが、出力を何度も繰り返していました。
あなたのスクリプトは実際には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
プロセスに勝ります。参考までに。
#!/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
の未設定変数の値がゼロに評価されるためです。