web-dev-qa-db-ja.com

Bashのプロセス置換をHERE-documentと組み合わせる方法は?

Bashバージョン4.2.47(1)-releaseで、ここにあるような次のような形式のテキストを分類しようとすると、次のようになります。

cat <(fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
) # I want this paranthesis to end the process substitution.

次のエラーが発生します。

bash: bad substitution: no closing `)' in <(fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
)

また、私はここにドキュメントを引用したくない、つまり<'FOOBAR'、その中で変数を置換したいので。

14
Tim Friske

プロセスの置換は、これとほぼ同じです。

例-プロセス置換のメカニズム

ステップ#1-fifoを作成し、それに出力します

_$ mkfifo /var/tmp/fifo1
$ fmt --width=10 <<<"$(seq 10)" > /var/tmp/fifo1 &
[1] 5492
_

ステップ#2-fifoを読み取る

_$ cat /var/tmp/fifo1
1 2 3 4
5 6 7 8
9 10
[1]+  Done                    fmt --width=10 <<< "$(seq 10)" > /var/tmp/fifo1
_

HEREDOC内での括弧の使用も問題ないようです。

例-FIFOを使用する

ステップ#1-FIFOへの出力

_$ fmt --width=10 <<FOO > /var/tmp/fifo1 &
(one)
(two
FOO
[1] 10628
_

ステップ#2-FIFOの内容を読み取ります

_$ cat /var/tmp/fifo1
(one)
(two
_

問題が発生していると思いますが、プロセス置換<(...)は、その中の括弧のネストを考慮していないようです。

例-プロセスサブ+ HEREDOCが機能しない

_$ cat <(fmt --width=10 <<FOO
(one)
(two
FOO
)
bash: bad substitution: no closing `)' in <(fmt --width=10 <<FOO
(one)
(two
FOO
)
$
_

かっこをエスケープすると少し落ち着くようです:

例-括弧のエスケープ

_$ cat <(fmt --width=10 <<FOO                 
\(one\)
\(two
FOO
)
\(one\)
\(two
_

しかし、あなたが本当にあなたに欲しいものを与えるわけではありません。括弧をバランスよくすることもそれをなだめるようです:

例-括弧のバランス

_$ cat <(fmt --width=10 <<FOO
(one)
(two)
FOO
)
(one)
(two)
_

Bashで対処するために、このような複雑な文字列がある場合は常に、ほとんどの場合、最初にそれらを構築し、変数に格納してから、変数を介して使用します。壊れやすい。

例-変数を使用する

_$ var=$(fmt --width=10 <<FOO
(one)
(two
FOO
)
_

それを印刷するには:

_$ echo "$var"
(one)
(two
_

参考文献

7
slm

これは単なる回避策です。プロセス置換を使用する代わりにfmtcatにパイプします

fmt --width=10 <<FOOBAR | cat 
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
3
iruvar

これは古い質問であり、これは不自然な例であることを理解している(したがって、正しい解決策はcat |または実際には、この場合はcatはありません)、一般的なケースの回答を投稿します。私はそれを関数に入れて代わりにそれを使用することで解決します。

fmt-func() {
    fmt --width=10 <<FOOBAR
(I want the surrounding parentheses to be part of the HERE-document)
(Even the preceding unbalanced parenthesis should be part of it.
FOOBAR
}

そしてそれを使う

cat <(fmt-func)
2
falstro