Ignora o espaçamento entre strings de eco

2

Eu uso echo para imprimir duas strings em um arquivo em um desses dois comandos:

echo -e "\n""x" >> ~/file
echo -e "\n" "x" >> ~/file

O primeiro resultado é:


x

O segundo resultado é:


 x

Eu assumo que você não perdeu o espaço extra.

Eu mais desejo que o segundo comando se comporte como o primeiro, porque o espaço extra entre "\n" e "x" torna mais confortável ler o comando.

Dado que não é possível, naturalmente, no Bash 4.3.48 (1), existe alguma sintaxe que permita ou, pelo menos, aproxime-se dela?

O objetivo principal é ter um espaçamento, ou pelo menos algum espaço reservado / separador, que me proporcione algum tipo de separação entre as duas strings, para uma leitura mais confortável, mas sem ter esse espaço extra acima.

Por favor, mostre como você sabe. Estou aberto para usar algo diferente de echo (embora eu prefira evitar o string here).

Note que usei o termo "string" para " \n ". Não tenho certeza se está correto aqui, mas é o melhor termo que tenho para descrever isso.

    
por user9303970 07.02.2018 / 13:26

4 respostas

3

Você pode fazer isso com o comando printf :

printf '\n%s\n' 'x' >file

Com echo , consegui fazer isso usando tr para excluir espaço em branco:

echo -e '\n x' | tr -d ' ' >file

Também pode ser escrito como (mas, por favor, não):

echo -e '\n' 'x' | tr -d ' ' >file

Resultados:

$ cat file

x

Eu suponho que também poderia ser facilmente argumentado que eles realmente dificultarão o seu comando .

    
por 07.02.2018 / 13:51
3

Se o ponto-chave estiver separando visualmente as duas strings ( \n e x , aqui) na origem do script, suponho que você possa colocá-las em variáveis:

str1='\n'
str2='x'
echo -e "$str1$str2" >> file

As expansões dos parâmetros são, claro, back-to-back, mas as strings em si não são.

Ou com printf , mas a adição da nova linha de rejeição deve ser feita separadamente:

{ printf %s $'\n' 'x'; echo; } >> file

%s , claro, não expande escapes de barra invertida da string de argumento, mas no Bash nós podemos usar as citações que $'...' ANSI-C faz. echo para obter a nova linha final.

Ou defina uma função para fazer o que quiser ( "$*" concatena os argumentos para a função, sem delimitador, pois IFS foi apagado aqui):

output() { local IFS=; echo -e "$*"; }
output "\n" "x"
    
por 07.02.2018 / 14:31
1

Se o objetivo for especificamente escrever uma nova linha e um x (e outra nova linha?) para um arquivo, sem que n e x apareçam consecutivamente (por exemplo, nx ) em seu comando (e sem incluir um espaço indesejado na sua saída), uma abordagem muito simples é

{ echo; echo "x";} >> file

(para escrever nova linha, x , nova linha) ou

{ echo; echo -n "x";} >> file

(para escrever nova linha e x , mas nenhuma nova linha no final). Você também pode usar parênteses em vez de chaves para agrupar:

(echo; echo "x") >> file

Note que, com chaves, você deve ter espaço em branco (espaço (s), tabulação (s) e / ou nova (s) linha (s)) após a abertura { , e você deve ter um ; (e / ou nova linha (s)) antes do fechamento } . Ou você pode fazer dois comandos totalmente separados (não agrupados) que redirecionam de forma independente:

echo     >> file
echo "x" >> file

Ou use a resposta de Jesse_b :

printf '\n%s\n' 'x' >> file

(para escrever nova linha, x , nova linha) ou

printf '\n%s'   'x' >> file

(para escrever nova linha e x , mas não há nova linha no final).

Mas se o objetivo é mais geral - escrever um monte de seqüências de caracteres (sem espaços intervenientes), enquanto os separa por espaços na linha de comando, considere

printf '%b' string …

em que %b é o formato de conversão para imprimir uma string com \ seqüências interpretadas (em contraste com %s , que imprime strings literalmente). Por exemplo,

printf '%b' '\n' foo '\t' bar

irá escrever nova linha foo guia bar ; ou seja,

 
foo     bar
(sem nova linha no final). Você também pode dizer
printf '%b%b%b%b' '\n' foo '\t' bar

mas você não precisa; o formato será aplicado quantas vezes forem necessárias para exibir todos os argumentos. Portanto, se você quiser adicionar uma nova linha no final,

printf '%b\n' '\n' foo '\t' bar

não funcionará; Ele adicionará uma nova linha após cada argumento. Você pode fazer

printf '%b' '\n' foo '\t' bar '\n'

(adicionando uma nova linha como argumento final) ou

printf '%b%b%b%b\n' '\n' foo '\t' bar

(contando os argumentos), ou

{ printf '%b' '\n' foo '\t' bar; echo;}

Ainda outra abordagem , se você estiver usando o bash, é

printf '%s' $'\n' foo $'\t' bar

usando a notação $'text…' do bash interpretar sequências \ . Aplicando isso à pergunta original, obteríamos

printf '%s' $'\n' x
    
por 07.02.2018 / 18:42
1

Você pode usar o %b (interpretar argumentos de back back) de bash printf:

$ printf  %b  \n  x  >> file

Claro, você pode citar o \n :

$ printf  %b  '\n'  x  >> file

Mas tenha muito cuidado com o que você alimenta no printf, já que qualquer valor de backquoted em vez de x será interpretado por printf.

Ou, como você está usando o bash, ele permite que uma nova linha seja gerada com $'\n' :

$ printf '%s' $'\n' x >>file

Um pouco mais seguro que %b .

Ou, se você quiser uma variável:

$ nl=$'\n'
$ printf '%s' "$nl" x >> file

Ou você pode definir uma função:

$ separate() { local IFS=; printf %b "$*"; }
$ separate '\n' 'x' '*'

O local IFS= garantirá que os argumentos sejam unidos (sem espaços intermediários) por "$*"

    
por 07.02.2018 / 18:32