web-dev-qa-db-ja.com

bashのPrintfの例は改行を作成しません

Bashスクリプトでprintfを使用する場合、"\n"の後にスペースを追加しても改行は作成されませんが、スペースを追加すると改行が作成されます。 g .:

  1. "\n"の後にスペースなし

    NewLine=`printf "\n"`
    echo -e "Firstline${NewLine}Lastline"
    

    結果:

    FirstlineLastline
    
  2. "\n "の後のスペース

    NewLine=`printf "\n "`
    echo -e "Firstline${NewLine}Lastline"
    

    結果:

    Firstline
     Lastline
    

質問:なぜ次の結果を作成しないのですか?

Firstline 
Lastline

この特定の問題は他の手法を使用して回避できた可能性があることはわかっていますが、なぜ1.が機能しないのかに焦点を当てたいと思います。

編集:printfの代わりにエコーを使用すると、期待どおりの結果が得られますが、なぜprintfの動作が異なるのですか?

    NewLine=`echo "\n"`
    echo -e "Firstline${NewLine}Lastline"

結果:

    Firstline
    Lastline
27
WolfHumble

バックティック演算子は、末尾の改行を削除します。 3.4.5を参照してください。コマンド置換at http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_03_04.html

編集された質問に関するメモ

比較:

[alvaro@localhost ~]$ printf "\n"

[alvaro@localhost ~]$ echo "\n"
\n
[alvaro@localhost ~]$ echo -e "\n"


[alvaro@localhost ~]$

Echoコマンドは、そうするように指示しない限り、\nを改行として扱いません。

NAME
       echo - display a line of text
[...]
       -e     enable interpretation of backslash escapes

POSIX 7はこの動作を規定しています here

[...]コマンドの標準出力で、置換の最後にある1つ以上の文字のシーケンスを削除します

28
$ printf -v NewLine "\n"
$ echo -e "Firstline${NewLine}Lastline"

Firstline
Lastline

$ echo "Firstline${NewLine}Lastline"
Firstline
Lastline
4
Robert S

多分人々は私が持っていたのと同じ問題でここに来るでしょう:バックスティックに包まれたコードの中に\ nをエコーし​​ます。少しヒント:

printf "astring\n"
# and 
printf "%s\n" "astring" 
# both have the same effect.
# So... I prefer the less typing one

短い答えは:

# Escape \n correctly !

# Using just: printf "$myvar\n" causes this effect inside the backsticks:
printf "banana
"

# So... you must try \\n  that will give you the desired 
printf "banana\n"

# Or even \\\\n if this string is being send to another place 
# before echoing,

buffer="${buffer}\\\\n printf \"$othervar\\\\n\""

一般的な問題の1つは、コード内で次のことを行う場合です。

echo 'Tomato is Nice'

バックスティックで囲まれるとエラーが発生します

command Tomato not found.

回避策は、別のecho -eまたはprintfを追加することです

printed=0

function mecho(){
  #First time you need an "echo" in order bash relaxes.
  if [[ $printed == 0 ]]; then
    printf "echo -e $1\\\\n"
    printed=1
  else
    echo -e "\r\n\r$1\\\\n"
  fi
}

これで、プロンプトで行うコードをデバッグできます。

(Prompt)$  `mySuperFunction "arg1" "etc"`

出力はうまくいきます

 mydebug: a value
 otherdebug: whathever appended using myecho
 a third string

そして内部でデバッグする

mecho "a string to be hacktyped"
4
Sergio Abreu

編集されたechoバージョンは、変数$NewLineにリテラルのバックスラッシュnを入れて、echo -eによって解釈されます。代わりにこれを行った場合:

NewLine=$(echo -e "\n")
echo -e "Firstline${NewLine}Lastline"

結果はケース1と同じになります。 thatを1つの方法で機能させるには、バックスラッシュをエスケープして、全体を一重引用符で囲む必要があります。

NewLine=$(printf '\\n')
echo -e "Firstline${NewLine}Lastline"

またはダブルエスケープします。

NewLine=$(printf "\\\n")

もちろん、printfを直接使用することも、次のようにNewLine値を設定することもできます。

printf "Firstline\nLastline\n"

または

NewLine=$'\n'
echo "Firstline${NewLine}Lastline"    # no need for -e
3

BASHが末尾の改行を削除しているようです。例えば.

NewLine=`printf " \n\n\n"`
echo -e "Firstline${NewLine}Lastline"
Firstline Lastline

NewLine=`printf " \n\n\n "`
echo -e "Firstline${NewLine}Lastline"
Firstline


 Lastline
3
an0nym0usc0ward

NewLine変数を作成するために「echo」または「printf」は必要ありません。

NewLine="
"
printf "%q\n" "${NewLine}"
echo "Firstline${NewLine}Lastline"
1
yabt