コマンド置換中に単語分割を無効にするにはどうすればよいですか?問題の簡単な例を次に示します。
4:00 PM/Users/paymahn/Downloads ❯❯❯cattest.txt hello\nworld 4:00 PM/Users/paymahn/Downloads ❯❯❯echo$(cat test.txt) hello world 4:00 PM/Users/paymahn/Downloads ❯❯❯echo " $(cat test.txt) " hello world 4:01 PM/Users/paymahn/Downloads ❯❯❯echo" $(cat "test。 txt ")" hello world
私が欲しいのは、echo $(cat test.txt)
(またはコマンドの置換を含むものの変形)がhello\nworld
を出力することです。
見つけました https://www.gnu.org/software/bash/manual/html_node/Command-Substitution.html 下部にIf the substitution appears within double quotes, Word splitting and filename expansion are not performed on the results.
と書いてありますが、作成できないようですその感覚。私がすでに試した例の1つはその規則に準拠していると思いましたが、そうではないと思います。
リテラルの\n
を改行に変更することは、単語の分割ではなく、echo
バックスラッシュの処理です。 echo
の一部のバージョンはそれを行い、一部は処理しません... Bashのecho
は、デフォルトでバックスラッシュエスケープを処理しません(-e
フラグまたはxpg_echo
なし)オプション)、しかし例えばダッシュとZshのバージョンのecho
はそうです。
$ cat test.txt
hello\nworld
$ bash -c 'echo "$(cat test.txt)"'
hello\nworld
$ zsh -c 'echo "$(cat test.txt)"'
hello
world
代わりにprintf
を使用してください。
$ bash -c 'printf "%s\n" "$(cat test.txt)"'
hello\nworld
$ zsh -c 'printf "%s\n" "$(cat test.txt)"'
hello\nworld
それにもかかわらず、shのようなシェルでの単語の分割やグロブを防ぐために、コマンド置換を引用符で囲む必要があります。 (zshは、shモードを除いて、コマンド置換時(パラメーターまたは算術展開時ではない)にのみワード分割(グロブではない)を行います。)
Zshによって実装されたエコーは、デフォルトでエスケープシーケンスを解釈します。最も簡単な解決策は次のとおりです。
$ echo -E "$(cat test.txt)"
hello\nworld
または
$ print -r "$(cat test.txt)"
正しい解決策は、printfを使用することです。
$ printf '%s\n' "$(<test.txt)"