awkはシェル文字列(変数)のフィールド識別子も使用できますか?

awkはシェル文字列(変数)のフィールド識別子も使用できますか?

まあ、私が試した方法では明らかに不可能です。

この選択肢を得ることができますバーただし、結果の文字列は有効です。

#!/bin/bash

path1=/usr/tmp/foo/bar/baz

awk -F/ '{print $5}' <<< "$path1"

これまでは大丈夫です。しかし、<<<演算子と悪名高いパイプを使用したくない場合はecho | ...どうすればよいですか?簡単に言えば、私がやりたいことは、path1ディレクティブを変数として渡すことです。-v pa="$path1"そして-F/のフィールド区切り記号とフィールド識別子を使用して$5解析されます。awk内部 pa値が次のような変数外部 path1シェル変数。 「社内」でも可能awkですか?

答え1

-vオプションや引数var=valueの問題awkは、ANSI Cエスケープシーケンス(例えば、\n... \b)が拡張され(GNU awk4.2以降では値がで始まり@/終わった場合は、/正規表現型の変数として扱われます。)。

もう 1 つの方法は、以下を使用またはARGV配置ENVIRON awkすることです。

awk -F / 'BEGIN{$0 = ARGV[1]; print $5}' "$path1"

または:

export path1
awk -F / 'BEGIN{$0 = ENVIRON["path1"]; print $5}'

または:

path1="$path1" awk -F / 'BEGIN{$0 = ENVIRON["path1"]; print $5}'

今、あなたが望むものがシェル変数を分割することであれば、これは必要ないかもしれませんawk

すべてのPOSIXシェルで:

IFS=/; set -f
set -- $path1
printf '%s\n' "$5"

答え2

pa配列に分けることができます

awk -F'/' -v pa=$path1 'BEGIN{split(pa, arr, FS); print(arr[5]); exit}'

答え3

awk環境変数をスクリプト/コマンドに渡す方法はいくつかあります。

方法1

これにより、シェルは$path1コマンドを実行する前に変数を拡張しますawk

$ echo $path1
/usr/tmp/foo/bar/baz
$ awk -F'/' 'END{a="'$path1'"; split(a,arr,FS); print(arr[5])}' /dev/null
bar

方法#2

環境を通して。の変数はawk変数ですa

$ awk -F '/' 'END{split(a,arr,FS); print(arr[5])}' a=$path1 /dev/null
bar

方法#3

awk変数を明示的に渡すには、スイッチを使用します-v

$ awk -F'/' -v a=$path1 'END{split(a,arr,FS); print(arr[5])}' /dev/null
bar

デバッグ

set -x何が起こっているかを確認するために、これらのコマンドを実行する前に設定してシェルの詳細情報を有効にすることができます。方法#2を例に挙げましょう。

$ set -x
$ awk -F '/' 'END{split(a,arr,FS); print(arr[5])}' a=$path1 /dev/null
+ awk -F / 'END{split(a,arr,FS); print(arr[5])}' a=/usr/tmp/foo/bar/baz /dev/null
bar

上記はset -xawk 行以降の実行を示しています。実行時間によっては、実行時間変数aの値が$path1拡張されていることを確認できます。

もう一つの例は今回は方法#1です。

$ awk -F'/' 'END{a="'$path1'";split(a,arr,FS); print(arr[5])}' /dev/null
+ awk -F/ 'END{a="/usr/tmp/foo/bar/baz";split(a,arr,FS); print(arr[5])}' 
bar

$path1ここでは、シェルが実行される前に変数を確実に拡張することがわかりますawk

答え4

どうですか?

basename "$(dirname "$path1")"

または、シェルがプロセス置換をサポートし、次を使用する必要がある場合awk

awk -F'/' '{print $5}' <(printf '%s\n' "$path1")

関連情報