概要
awk への値の受け渡しの記事はよく見かけるが
awk からシェルへの値の受け渡しの記事が少ないのでまとめてみた。
シェルから awk への値の受け渡し
awk への値の受け渡しは -v オプションを使うと覚えておけば間違いない。
シェルからawkへの値の受け渡し
#!/bin/sh
# -v オプションで値を手入力
echo | awk -v foo=before '{print foo}'
# 実行結果: before
# 後ろには書けない
echo | awk '{print foo}' -v foo=after
# 実行結果: awk: fatal: cannot open file `-v' for reading (No such file or directory)
# -v 無しで渡す方法もあるが、BEGINブロックで値を参照できない
echo | awk 'BEGIN{print foo} {print foo} END{print foo}' foo="Not an option"
# 実行結果:
# 実行結果: Not an option
# 実行結果: Not an option
# -v オプションを使うほうが望ましい
echo | awk -v foo="This is an option" 'BEGIN{print foo} {print foo} END{print foo}'
# 実行結果: This is an option
# 実行結果: This is an option
# 実行結果: This is an option
# 複数指定できる
echo | awk -v foo=first -v bar=second '{print foo, bar}'
# 実行結果: first second
# 変数の値を渡すこともできる
hoge="hello"
fuga="world"
echo | awk -v foo=${hoge} -v bar="$fuga" '{print foo, bar}'
# 実行結果: hello world
# コマンドの実行結果を渡すこともできる
echo | awk -v foo="$( echo 'hello world' | sed -e 's/world/japan/' )" '{ print foo }'
# 実行結果: hello japan
# パイプとの組み合わせ
echo "world" | awk -v foo="hello" '{ bar=foo FS $0; print bar }' | echo -e $(cat)
# 実行結果: hello world
# awk のスクリプト内に直接書く
hoge="hello"
fuga="world"
echo | awk 'BEGIN {print "'"$hoge"'","'"$fuga"'"}'
# 実行結果: hello world
# 文字列のリダイレクト
hoge="hello world"
echo | awk '{print $0}' <<< "$hoge"
# 実行結果: hello world
参照:
awkコマンドへ値を渡す手法のまとめ
awkからシェル変数を参照する
How do I use shell variables in an awk script?
awk からシェルへの値の受け渡し
単一なら $() で代入、
複数なら read で代入が分かりやすい。
awkからシェルへの値の受け渡し
#!/bin/sh
# awk の出力値をバッククォートで囲い、変数に入れる
account_name=`awk -F@ '{print $1}' <<< "account1@domain.com"`
echo ${account_name}
# 実行結果: account1
# 以下も同じく awk の出力値を $() を使って変数に入れる。
account_name=$(awk -F@ '{print $1}' <<< "account2@domain.com")
echo ${account_name}
# 実行結果: account2
# awk の出力を eval で評価する
eval `awk -F@ '{ printf("account_name=\"%s\" ; domain_name=\"%s\"",$1,$2) }' <<< "account3@domain.com"`
echo ${account_name}
echo ${domain_name}
# 実行結果: account3
# 実行結果: domain.com
# 以下も同じ
eval $(awk -F@ '{ printf("account_name=\"%s\" ; domain_name=\"%s\"",$1,$2) }' <<< "account4@domain.com")
echo ${account_name}
echo ${domain_name}
# 実行結果: account4
# 実行結果: domain.com
# set コマンドにて位置パラメータに一旦渡し、それを参照する
set $(awk -F@ '{print $1, $2}' <<< "account5@domain.com")
account_name=$1
domain_name=$2
echo ${account_name}
echo ${domain_name}
# 実行結果: account5
# 実行結果: domain.com
# awk の出力値をreadを使って変数に入れる
read account_name domain_name <<< $( awk -F@ '{print $1, $2}' <<< "account6@domain.com" )
echo ${account_name}
echo ${domain_name}
# 実行結果: account6
# 実行結果: domain.com
# 配列への格納
declare -a array=()
mapfile -t array <<< $( awk -F@ '{print $1, $2}' <<< "account7@domain.com" )
echo "${array[@]}"
# 実行結果: account7 domain.com
以下は <() を使っているので bash でないと機能しない。
bashでないと機能しない
#!/bin/bash
# awk の出力を source で評価する
source <(awk -F@ '{ printf("account_name=\"%s\" ; domain_name=\"%s\"",$1,$2) }' <<< "account8@domain.com")
echo ${account_name}
echo ${domain_name}
# 実行結果: account8
# 実行結果: domain.com
# awk の出力値をreadを使って変数に入れる
read account_name domain_name < <( awk -F@ '{print $1, $2}' <<< "account9@domain.com" )
echo ${account_name}
echo ${domain_name}
# 実行結果: account9
# 実行結果: domain.com
# 配列への格納
declare -a array=()
mapfile -t array < <( awk -F@ '{print $1, $2}' <<< "account10@domain.com" )
echo "${array[@]}"
# 実行結果: account10 domain.com