コマンドの置換中に単語の区切りを無効にする方法は?以下は問題の簡単な例です。
午後4時/ユーザー/paymahn/ダウンロード ❯❯❯猫テスト.txt こんにちは。\ n 午後4時/ユーザー/paymahn/ダウンロード ❯❯❯ エコ$(cat test.txt) こんにちは 世界 午後4時/ユーザー/paymahn/ダウンロード ❯❯❯ echo "$(cat test.txt)" こんにちは 世界 午後4時1分/ユーザー/paymahn/ダウンロード ❯❯❯ echo "$(cat "test.txt" )" こんにちは 世界
私が望むのは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つはそのルールに合うと思ったが、そうではないようだ。
答え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
また見なさい:なぜprintfがechoより優れているのですか?
それにもかかわらず、shなどのシェルでワードセパレータとワイルドカードを回避するには、コマンドの代わりに引用符を入れる必要があります。 (shモードを除いて、zshはコマンドの代入(引数または算術拡張ではない)時にのみトークン化(ワイルドカードではない)を実行します。)
答え2
echoのzsh実装は基本的にエスケープシーケンスを解釈します。最も簡単な解決策は次のとおりです。
$ echo -E "$(cat test.txt)"
hello\nworld
または
$ print -r "$(cat test.txt)"
正しい解決策はprintfを使用することです。
$ printf '%s\n' "$(<test.txt)"