6

今日、Bashprintf-vオプションがあることに気付きました

-v var    assign the output to shell variable VAR rather than
          display it on the standard output

このように呼び出すと動作します

$ printf -v var "Hello world"

$ printf "$var"
Hello world

パイプから来るとうまくいきません

$ grep "Hello world" test.txt | xargs printf -v var
-vprintf: warning: ignoring excess arguments, starting with `var'

$ grep "Hello world" test.txt | xargs printf -v var "%s"
-vprintf: warning: ignoring excess arguments, starting with `var'
4

3 に答える 3

9

xargs/usr/bin/printf(またはそのバイナリがシステムにインストールされている場所)を呼び出します。bash の組み込み関数は呼び出されません。そして、シェルの環境を変更できるのは、ビルトイン (またはスクリプトなどのソース) だけです。

bashのビルトインを呼び出すことができたとしてもxargs、あなたの例ではサブセルで実行されます。とにかく、サブシェルはその親の環境を変更できません。だからあなたがしようとしていることはうまくいきません。

あなたのサンプルを正しく理解していれば、いくつかのオプションが表示されます。サンプルデータ:

$ cat input
abc other stuff
def ignored
cba more stuff

単純な変数 (正確に何を望むかによっては少しトリッキーです):

$ var=$(grep a input)
$ echo $var
abc other stuff cba more stuff
$ echo "$var"
abc other stuff
cba more stuff

配列内の個々の単語が必要な場合は、配列を使用します。

$ var=($(grep a input))
$ echo "${var[0]}"-"${var[1]}"
abc-other

または、各配列要素の行全体が必要な場合:

$ IFS=$'\n' var=($(grep a input)) ; unset IFS
$ echo "${var[0]}"-"${var[1]}"
abc other stuff-cba more stuff
于 2012-06-12T20:10:16.753 に答える
1

2 つの printf があります。1 つは shell bultin で、これは printf を実行しただけで呼び出され、もう 1 つは通常のバイナリ (通常は /usr/bin/printf) です。後者は -v 引数を取らないため、エラー メッセージが表示されます。printfはここへの引数であるためxargs、シェル bulitin ではなく、バイナリが実行されます。さらに、パイプラインの受信側にあるため、サブプロセスとして実行されます。変数は親プロセスから子プロセスにのみ継承できますが、その逆は継承できません。そのため、printf バイナリが環境を変更できたとしても、その変更は親プロセスには表示されません。したがって、コマンドが機能しない理由は 2 つあります。しかし、いつでもできますvar=$(something | bash -c 'some operation using builtin printf')

于 2012-06-12T20:10:52.307 に答える
0

Mat は、何が起こっているのか、その理由について優れた説明を提供します。

sprintfコマンドの出力を反復処理し、Bash のスタイルprintf機能 ( )を使用して変数に連続する値を設定する場合は、次の-vように実行できます。

grep "Hello world" test.txt | xargs bash -c 'printf -v var "%-25s" "$@"; do_something_with_formatted "$var"' _ {} \;
于 2012-06-12T21:38:40.273 に答える