web-dev-qa-db-ja.com

Printfはバックスラッシュと感嘆符の解釈に失敗します

printfを使用して端末からJavaプログラムを作成し、その出力を.Javaファイルにリダイレクトしていますが、printfは水平バックスラッシュタブの解釈に失敗します(\t)、文字列に感嘆符(!)があると、印刷も行われず、次のエラーで失敗します。

bash: !": event not found

  • Printfに水平タブを含めるにはどうすればよいですか?

  • そして、上記のエラーを取得せずに感嘆符を含めるにはどうすればよいですか?

コマンドライン引数:

$ printf "%s\n" "public class {" "\tpublic static void main(String[] args) {" "dogBark()" "}" "public static void dogBark() {" "System.out.println("Woof")" "}" "}" > barkingDog.Java

.Javaファイルからの出力

$ less barkingDog.Java
public class {
\tpublic static void main(String[] args) {
dogBark()
}
public static void dogBark() {
System.out.println(Woof)
}

}
2
MyWrathAcademia

ヒアドキュメントを使用すると、printfを使用するよりもクリーンで保守が簡単になります。ただし、bashシェルの組み込みのhelp printfから

 %b   expand backslash escape sequences in the corresponding argument

bash!を履歴拡張として扱わないようにするには、文字列を一重引用符で囲みます。

$ printf '%b\n' 'public class {' '\tpublic static void main(String[] args) {' 'dogBark()' '}' 'public static void dogBark() {' 'System.out.println("Woof!")' '}' '}'
public class {
    public static void main(String[] args) {
dogBark()
}
public static void dogBark() {
System.out.println("Woof!")
}
}

強打をエコーする方法! を参照してください

7
steeldriver

printfは、出力される文字列内のバックスラッシュ文字(\tなど)を解釈できません。フォーマット文字列のみ:

$ printf '\t%s' "test" "string"
    test    string

回避策として、印刷する文字列に実際のタブを挿入できます。

バックスラッシュ文字を解釈できる%bのフォーマット文字列を使用することができます。

$ printf '%b' "\ttest" "\tstring"
    test    string

文字!は履歴の展開に使用されます。しかし、それは引用符なしで使用された場合にのみ発生します。引用するだけで(\ではなく'または"で)拡張を防ぐことができます。それでも問題が解決しない場合は、履歴の拡張を無効にすることができます。

$ set +H

これは機能するはずです:

$ printf "%b\n" \
         "public class {" \
         "\tpublic static void main(String[] args) {" \
         "dogBark()" \
         "}" \
         "public static void dogBark() {" \
         "System.out.println(\"Woof\!\")" \
         "}" \
         "}" > barkingDog.Java

$ cat barkingDog.Java 
public class {
        public static void main(String[] args) {
dogBark()
}
public static void dogBark() {
System.out.println("Woof!")
}
}

しかし、明らかに、ヒアドキュメントはより単純です。

$ cat <<\EOT >barkingDog.Java
public class {
       public static void main(String[] args) {
dogBark()
}
public static void dogBark() {
System.out.println("Woof!")
}
}
EOT
3
Isaac

私はあなたが次のようにANSI-C引用を使用してあなたが望むことを達成できると思います:

printf "%s\n" "public class {" \
$'\tpublic static void main(String[] args) {' \
"dogBark()" \
"}" \
"public static void dogBark() {" \
"System.out.println("Woof")" \
"}" \
"}" > barkingDog.Java

出力:

public class {
        public static void main(String[] args) {
dogBark()
}
public static void dogBark() {
System.out.println(Woof)
}
}

感嘆符については、履歴の展開が有効になっている場合、bashは二重引用符で囲まれているときに!を展開しようとします。したがって、一重引用符で囲むか、\でエスケープします。

0
jesse_b