[解決済み] [Solved] awk スクリプトでシェル変数を使うには?
質問
外部シェル変数を
awk
スクリプトを作成しましたが
'
と
"
.
まず、シェルスクリプトで試してみました。
$ v=123test
$ echo $v
123test
$ echo "$v"
123test
次にawkを試してみました。
$ awk 'BEGIN{print "'$v'"}'
$ 123test
$ awk 'BEGIN{print '"$v"'}'
$ 123
なぜ違うのでしょうか?
最後にこんなことをやってみました。
$ awk 'BEGIN{print " '$v' "}'
$ 123test
$ awk 'BEGIN{print ' "$v" '}'
awk: cmd. line:1: BEGIN{print
awk: cmd. line:1: ^ unexpected newline or end of string
これには困りましたね。
どのように解決するのですか?
<ブロッククオート
#シェル変数の取得
awk
は、いくつかの方法で行うことができます。いくつかの方法は、他の方法よりも優れています。これはそのほとんどをカバーするはずです。 もし、コメントがあれば、下に残してください。
使用方法
-v
(最も良い方法、最もポータブルな方法)
を使用します。
-v
オプション: (P.S.)
-v
にしないと、移植性が悪くなります。例
awk -v var=
ではなく
awk -vvar=
)
variable="line one\nline two"
awk -v var="$variable" 'BEGIN {print var}'
line one
line two
これは、ほとんどの
awk
という変数があり、その変数が
BEGIN
ブロックも同様です。
複数の変数がある場合。
awk -v a="$var1" -v b="$var2" 'BEGIN {print a,b}'
警告
. Ed Morton が書いているように、エスケープシーケンスは次のように解釈されます。
\t
は本当の
tab
であって
\t
を検索してください。を使用することで解決できます。
ENVIRON[]
を経由してアクセスするか
ARGV[]
PS
3本の縦棒をセパレータとして使用する場合
|||
を使用すると、エスケープすることができません。
-F"[|][|][|]"
プログラム/関数innからデータを取得する例
awk
(ここでは日付が使われています)
awk -v time="$(date +"%F %H:%M" -d '-1 minute')" 'BEGIN {print time}'
シェル変数の内容を正規表現でテストする例です。
awk -v var="$variable" '$0 ~ var{print "found it"}'
コードブロックの後の変数
の後に変数を取得します。
awk
というコードがあります。の中で変数を必要としない限り、これは問題なく動作します。
BEGIN
ブロックを作成します。
variable="line one\nline two"
echo "input data" | awk '{print var}' var="${variable}"
or
awk '{print var}' var="${variable}" file
- 複数の変数を追加する。
awk '{print a,b,$0}' a="$var1" b="$var2" file
-
この方法で、異なるフィールドセパレータを設定することもできます。
FS
を各ファイルごとに設定します。
awk 'some code' FS=',' file1.txt FS=';' file2.ext
-
コードブロックの後にある変数は
BEGIN
ブロックを作成します。
echo "input data" | awk 'BEGIN {print var}' var="${variable}"
ここに文字列
また、変数は
awk
を使用しています。
ここで文字列
をサポートするシェル(Bashを含む)から入手できます。
awk '{print $0}' <<< "$variable"
test
と同じである。
printf '%s' "$variable" | awk '{print $0}'
追伸:これは変数をファイル入力として扱います。
ENVIRON
入力
TrueYさんが書かれているように
ENVIRON
を印刷する
環境変数
.
AWKを実行する前に変数を設定すると、このように出力することができます。
X=MyVar
awk 'BEGIN{print ENVIRON["X"],ENVIRON["SHELL"]}'
MyVar /bin/bash
ARGV
入力
スティーブン・ペニー氏が書いているように
ARGV
を使用して、データを awk に取り込みます。
v="my data"
awk 'BEGIN {print ARGV[1]}' "$v"
my data
BEGINだけでなく、コードそのものにデータを取り込むため。
v="my data"
echo "test" | awk 'BEGIN{var=ARGV[1];ARGV[1]=""} {print var, $0}' "$v"
my data test
コード内の変数。注意深く使用する
の中で変数を使用することができます。
awk
というコードがありますが、ごちゃごちゃして読みにくいですし、また
Charles Duffy
が指摘するように、このバージョンもコードインジェクションの犠牲となる可能性があります。 もし誰かがこの変数に悪いものを追加すると、それが
awk
というコードがあります。
これは、コードの中で変数を抽出し、その一部を構成するように動作します。
を作りたい場合は
awk
しかし、通常の変数には使用しないでください。
variable="line one\nline two"
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
コードインジェクションの例です。
variable='line one\nline two" ; for (i=1;i<=1000;++i) print i"'
awk 'BEGIN {print "'"$variable"'"}'
line one
line two
1
2
3
.
.
1000
にたくさんのコマンドを追加することができます。
awk
このように 有効でないコマンドでクラッシュさせることもできます。
しかし、この方法の有効な使い方のひとつは、単純な計算機のような入力に対して適用されるシンボルを awk に渡したい場合です。
$ calc() { awk -v x="$1" -v z="$3" 'BEGIN{ print x '"$2"' z }'; }
$ calc 2.7 '+' 3.4
6.1
$ calc 2.7 '*' 3.4
9.18
シェル変数の値を代入した awk 変数を使ってこれを行う方法はありません。awk が解釈する前に、シェル変数を展開して awk スクリプトのテキストの一部とする必要があります。
おまけ情報
ダブルクォートの使用
変数のダブルクォートは常に有効です。
"$variable"
そうでない場合は、複数の行が長い一行として追加されます。
例
var="Line one
This is line two"
echo $var
Line one This is line two
echo "$var"
Line one
This is line two
その他のエラーはダブルクォートでなくても取得可能です。
variable="line one\nline two"
awk -v var=$variable 'BEGIN {print var}'
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ backslash not last character on line
awk: cmd. line:1: one\nline
awk: cmd. line:1: ^ syntax error
また、シングルクォートを使用すると、変数の値を展開しない。
awk -v var='$variable' 'BEGIN {print var}'
$variable
AWKと変数についての詳細情報
このFAQを読む .
関連
-
[解決済み] Bashスクリプトのソースディレクトリをスクリプト自体から取得するにはどうすればよいですか?
-
[解決済み] プログラムの実行やシステムコマンドの呼び出しはどのように行うのですか?
-
[解決済み] Bashシェルスクリプトでディレクトリが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] Bashで文字列変数を連結する方法
-
[解決済み] Bashで文字列が部分文字列を含むかどうかをチェックする方法
-
[解決済み] シェルで、「2>&1」はどういう意味ですか?
-
[解決済み] Bashスクリプトからプログラムが存在するかどうかを確認するにはどうすればよいですか?
-
[解決済み] LinuxのシェルスクリプトでYes/No/Cancelの入力を促すにはどうしたらいいですか?
-
[解決済み] Bashシェルスクリプトの入力引数の存在確認
-
[解決済み] シェルスクリプトでブール変数を宣言して使用するにはどうすればよいですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] '\r': command not found - .bashrc / .bash_profile [duplicate].
-
[解決済み] ファイルに書き込むが、ファイルが存在する場合は上書きする
-
[解決済み] Docker ubuntu イメージ - bash: man: コマンドが見つかりません。
-
[解決済み] Bashでの動的な変数名
-
[解決済み] mkdir コマンドが bash スクリプトで見つかりません。
-
[解決済み] プロジェクトからすべての .pyc ファイルを削除するにはどうすればよいですか?
-
[解決済み] あいまいなリダイレクト」エラーが発生する
-
解決策:bash: /root/.bashrc: パーミッションが拒否されました
-
[解決済み] condaのアップデート後、ターミナルのプロンプトから(base)を削除する方法
-
[解決済み] ファイル内の大文字・小文字を区別しない文字列を grep するには?