Printf não consegue interpretar a barra invertida e o ponto de exclamação

2

Estou escrevendo um programa java do terminal usando printf e redirecionando sua saída para um arquivo .java , mas printf não consegue interpretar a guia de barra invertida horizontal ( \t ) e quando tenho um ponto de exclamação ( !) na string, nem sequer imprime e falha com este erro:

bash: !": event not found

  • Como forçar o printf a incluir uma guia horizontal?

  • E como incluo um ponto de exclamação sem receber o erro acima?

argumento da linha de comando:

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

saída do arquivo .java

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

}
    
por MyWrathAcademia 07.07.2018 / 22:11

3 respostas

7

Usar um documento aqui provavelmente seria mais limpo e mais fácil de manter do que usar printf . No entanto, a partir do help printf

do shell bash
 %b   expand backslash escape sequences in the corresponding argument

e para impedir que bash trate ! como expansão de histórico, aspas simples:

$ 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!")
}
}

Veja Como ecoar um estrondo!

    
por 07.07.2018 / 22:21
2

printf não pode interpretar caracteres de barra invertida (como \t ) na sequência impressa. Apenas na string de formato:

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

Como solução alternativa, você pode inserir uma guia real na string para imprimir.

É possível usar uma string de formato de %b que poderia interpretar caracteres de barra invertida:

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

O caractere ! é usado para expansão do histórico. Mas isso só acontece quando usado sem aspas. Apenas citá-lo (com \ ou ' não " ) deve impedir a expansão. Se isso ainda for um problema, a expansão do histórico pode ser desativada:

$ set +H

Isso deve funcionar:

$ 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!")
}
}

Mas, claramente, um documento aqui é mais simples:

$ cat <<\EOT >barkingDog.java
public class {
       public static void main(String[] args) {
dogBark()
}
public static void dogBark() {
System.out.println("Woof!")
}
}
EOT
    
por 07.07.2018 / 22:29
0

Acho que você pode realizar o que quiser usando as citações ANSI-C da seguinte forma:

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

Saída:

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

Quanto ao ponto de exclamação, quando a expansão de histórico é ativada, o bash tentará expandir ! quando estiver entre aspas duplas. Então faça uma citação simples ou escape com \ .

    
por 07.07.2018 / 22:18