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

使用此处文档可能比使用printf.但是,从 bash shell 的内置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 将!在双引号内尝试扩展。所以单引号它或用 转义它\

相关内容