awkでif条件を実装したいです。以下のように「simple_if」というファイル名を作成しました。
BEGIN{
num=$1;
if (num%2==0)
printf "%d is Even number.\n",num;
else printf "%d is odd Number.\n",num
}
次に、次のように$ 1のパラメータに10を渡してプログラムを実行します。
awk -f simple_if 10
ただし、入力を許可せず、代わりにゼロを表示します。出力:
0 is Even number.
awkでユーザーから価値を得る方法は?
答え1
コマンドラインの末尾に指定された引数は通常、スクリプトが読み取るファイル名awk
として扱われます。awk
コマンドラインで変数を設定するには-v variable=value
を使用します。
awk -v num=10 -f script.awk
これにより、num
スクリプト内の変数として使用できます。上記の例では、変数の初期値は10です。
ENVIRON["variable"]
スクリプトで読み取り環境変数を使用するか(名前付き環境変数の場合variable
)、コマンドライン引数を表示することもできます。ここでは正の整数ですARGV[n]
。n
$1
in を使用すると、awk
現在のレコードの最初のフィールド値を参照しますが、ブロック内で使用するため、まだファイルBEGIN
からデータを読み取っていません。
コードの数は算術コンテキストで使用される空の変数なので、ゼロと解釈されます。
答え2
$1
最初のコマンドライン引数ではなく、行が分割された後の最初のフィールドです(まだ行が分割されていないので空のFS
文字列になります)。BEGIN
コマンドラインパラメータは配列にありますARGV
。
$ awk 'BEGIN { for(i = 1; i < ARGC; i++) print ARGV[i] }' 1st 2nd 3rd
1st
2nd
3rd
ARGV[0]
常に通訳者の名前(awk
またはgawk
など)です。
awk
コマンドライン引数を無視して後でファイルとして開かないようにするには、それを削除するか空の文字列に設定する必要があります。例:ARGV[1]=""
。
ちなみに、この型のすべての引数はvar=value
の変数割り当てとして解釈されawk
評価されます。後ろにすでに処理される前のファイルパラメータ:
$ echo yes > file
$ awk '{ gsub(/e/, var); print }' var=1 file var=2 file var=3 file
y1s
y2s
y3s
フォームの実際のファイル名を使用するには、相対パスkey=val
またはawk
絶対パスで渡す必要があります。awk '{...}' ./key=val
。
答え3
user313992が言及した重要な点を指摘したいと思います。回答。
awkがコマンドライン引数を無視して後でファイルとして開かないようにするには、それを削除するか空の文字列に設定する必要があります。 ARGV[1]=""。
POSIX awkによると文書、引数は次のとおりです。ただ2つの形式のうちの1つとして解釈されます。
- 読み取るファイル
- 課題フォーマット:
var=val
したがって、指定されたパラメータが既存のファイルではなく割り当て形式ではない場合、ただこのパラメータを読んだ後、awkは失敗します。
BEGIN {
# this is OK:
for (i=1; i<ARGC; i++) {
print "+++ ", ARGV[i]
}
# action blocks will fail, because file reading has started
{
print $1
}
したがって、存在しないパラメータをファイルとして指定することも可能ですが、そのブロックでARGV
操作を実行する前にそのパラメータを削除する必要があることに注意してください。
はい -
#!/bin/awk -f
#
# Bin count using thresholds given at argv. E.g.
#
# ./bin_count 0.1 0.01 0.001 0.0001 <./data | sort
# < 0.000100: 3
# < 0.001000: 12
# < 0.010000: 56
# < 0.100000: 100
BEGIN {
for (i=1; i<ARGC; i++) counts[ARGV[i]] = 0
delete ARGV # <<<<< important
}
{
$1 = $1 < 0 ? -$1 : $1
for (bin in counts) {
if ($1 < bin) { counts[bin]++; }
}
}
END {
for (bin in counts) {
printf("< %f: %d\n", bin, counts[bin])
}
}
答え4
他のC類似プログラムと同様に、一般的なAwkはGNUgawk
固有の動作、パイプ、リダイレクト(<
)、または-v
(変数割り当て)オプションを使用せずにコマンドライン引数を処理することに問題はありません。
入力パラメータ処理ARGC
(パラメータ計算、整数)およびARGV
(パラメータベクトル、「リスト」の別の単語)がすべて含まれています。手動。
Mosvyは背景を説明し、構文解析を要約することをうまく行いますARGV
。これは、スタンドアロンシェルスクリプトとして実装され、macOSとGNU / Linuxでテストされた元の目標です。
simple_if.awk
#!/usr/bin/awk -f
##
## simple_if - tell user if a number given as an argument is even or odd
##
## Example: ./simple_if.awk 11
##
BEGIN {
num = ARGV[1];
# if you expect to arguments AND read from one or more input files, you need
# to remove the arguments from ARGV so Awk doesn't attempt to open them as
# files (causing an error)
#ARGV[1] = "";
if (num % 2 == 0) {
printf "%d is an even number.\n", num;
} else {
printf "%d is an odd number.\n", num;
}
}
このようなawkスクリプトを作成してください。実行可能ファイルを使用するにchmod a+x scriptname.awk
は にドロップすると、$PATH
他のBash、Python、Perlスクリプト、Cプログラムなどと同様に実行されます。
awk
システムの他の場所に存在する場合は、#!
その行を適切に更新してください/usr/bin/env
。awk
〜しなければならない-f
スクリプトを実行するオプションがあります...複雑。
名前.awk
は必須ではありません。別の言葉しかし、エディタが適切な構文強調を有効にするのに役立ちます。この機能をオフにすると、誰もそれがAwkスクリプトであるかどうかを知る必要はありません。
以下は、有用なタスクを実行し、合理的なエラー処理機能を備えたより完全な例です。
simple_stats.awk
#!/usr/bin/awk -f
##
## simple_stats - do simple 1-variable statistics (min/max/sum/average) on
## the first column of its input file(s)
##
## examples: ./simple_stats min numbers.txt
## ./simple_stats all numbers.txt # all stats
## ./simple_stats sum <(du MyFiles) # Bash proc. substitution
##
## # specify '-' as the filename when reading from stdin
## seq 1 100 | ./simple_stats avg -
##
BEGIN {
# expect stats operation as the first argument
op = ARGV[1]
# unset this array index so Awk doesn't try opening it as a file later
# ref: https://www.gnu.org/software/gawk/manual/html_node/ARGC-and-ARGV.html
ARGV[1] = ""
# if you wanted to process multiple command line arguments here, you could
# loop over ARGV, using something like
# for (i=0; i<ARGC; i++) { if (ARGV[i] == "...") { ... } }
if (op !~ /^(min|max|sum|avg|all)$/) {
print "ERROR: Expected one of min/max/sum/avg/all." >"/dev/stderr"
# 'exit' in BEGIN will always run the EXIT block, if one exists
# see https://www.gnu.org/software/gawk/manual/html_node/Assert-Function.html
_assert_exit = 1
exit 1
}
# ordinarily Awk reads stdin without specifying; here, '-' seems necessary
if (ARGV[2] == "") {
print "ERROR: Need an input file (or '-' for stdin)." >"/dev/stderr"
_assert_exit = 1
exit 1
}
}
# 'min' needs an initial value so take the first record
NR == 1 { min = $1 }
# for every input line (including the first)...
{
sum += $1
if ($1 > max) max = $1
if ($1 < min) min = $1
}
END {
if (_assert_exit) exit 1; # if 'exit' was pending from BEGIN block
if (op == "min" || op == "all")
printf "The minimum is: %15d\n", min
if (op == "max" || op == "all")
printf "The maximum is: %15d\n", max
if (op == "sum" || op == "all")
printf "The sum is: %15d\n", sum
if (op == "avg" || op == "all")
printf "The average is: %15.2f\n", sum/NR
}