まあ、私が試した方法では明らかに不可能です。
この選択肢を得ることができますバーただし、結果の文字列は有効です。
#!/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 awk
4.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 -x
awk 行以降の実行を示しています。実行時間によっては、実行時間変数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")