スラッシュを含む文字列をsedに渡して値を抽出する必要がありますが、そうしようとすると、その文字列をディレクトリ/ファイルとして扱い、「対応するディレクトリまたはファイルがありません」というエラーが発生します。私はこれがパスとして読み取られ、意図した効果ではないときにファイルを見つけようとするためだと仮定します。例:
my_value="my/value"
operand="$($my_value | sed -n -e 's/^\(.*\)\/.*/\1/p')"
# Expected echo $operand : my
注:私はbashスクリプトに最初に触れたので、これは間違ったアプローチかもしれません。
答え1
目的の出力がecho $operand
ある場合、my
次の1つの欠落を除いて構文は問題ありません。
operand="$(echo $my_value | sed -n -e 's/^\(.*\)\/.*/\1/p')"
その値をstdoutに送信して操作を実行するには、変数を使用する必要がecho
あります。変数値であるファイルまたはディレクトリが実際に呼び出されないため、エラーが発生します。my_value
sed
my/value
上記operand
の変数のコマンド置換は、使用時に出力されますecho
。my
echo $operand
別の方法は次のとおりです。
operand="$(printf '%s\n' "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"
printf
これは、含まれている他の文字列に対してechoが機能しないようにするより良いケースの1つです。この場合は発生しませんが、他の場合には発生する可能性があります。
答え2
ビルドするパイプラインは、あるコマンドの出力を別のコマンドの入力として使用します。名前付きファイルを実行しようとしていますが、そのファイルが存在しないというmy/value
メッセージが表示されることがあります。
必要なことを行う方法はいくつかあります。
この方法は依然としてパイプを使用し、おそらく最も移植性に優れています。
operand="$(echo "$my_value" | sed -n -e 's/^\(.*\)\/.*/\1/p')"
シェルがそれをサポートしている場合、代替は次のとおりです(少なくともbashでは機能する必要があります)。
operand="$(sed -n -e 's/^\(.*\)\/.*/\1/p' <<< "$my_value")"
後者のアプローチは、変数の値を表示するために追加のプロシージャを呼び出さないため、少し優先されます。
どちらの場合も、変数の内容を二重引用符で保護するのが最善です。
答え3
$my_value
他の人が指摘したように、コマンド置換からコマンドとして値を実行しようとしています。
/
文字列の最初の項目以降のすべての項目を削除するには、コマンド置換を使用します。
my_value="this/is/my/value"
operand=${my_value%%/*}
printf '%s\n' "$operand" # will output the string "this"
パラメータ拡張のため、${my_value%%/*}
一致する最も長いサフィックス文字列が/*
valueから削除されます$my_value
。これは標準パラメータ拡張そしてシェルは呼び出しよりはるかに速く実行されますsed
。
また、inの$my_value
値パス名、sed
技術的に改行文字を含めることができるので、操作するのは危険です。改行文字を含むパス名を処理するには、シェルでパラメーター拡張を使用します。