Printfはバックスラッシュと感嘆符を解釈できません。

Printfはバックスラッシュと感嘆符を解釈できません。

ターミナルでJavaプログラムを作成し、printf出力をファイルにリダイレクトしてい.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)
}

}

答え1

ここでは、ドキュメントを使用する方が.bashprintfシェルの組み込みを使用するよりも優れています。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!")
}
}

バラより大きな音を出す方法!

答え2

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

次のように、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は!二重引用符内で拡張を試みます。だから一重引用符で囲むかエスケープしてください\

関連情報