Caminho 1: escape instâncias de \ que você não quer escapar de outros personagens.
Com base no conteúdo da sua string, você provavelmente vai querer:
echo -e 'writes (>> appends) in note.txt this text\non 2 lines (with "-e" and "\n" help)' >> note.txt
O texto anexado a note.txt é:
writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)
As alterações são:
- Você tinha
/nonde parecia que você queria uma quebra de linha. Então eu mudei para\n. - No texto
with "-e" and "\n", o\deve ser impresso literalmente, em vez de combinar com onque o segue e produzir uma nova linha. Então eu citei (escapei)\com outro\. Se\nproduzir uma nova linha,\nproduzirá\n. -
Substitui as aspas duplas externas (
") por aspas simples ('). Você queria que os caracteres"em torno de-ee\nfossem impressos literalmente, mas terminaram e reiniciaram a cotação, impedindo que eles sejam impressos e fazendo com que\nseja realmente impresso comon(porque não foi marcado\né processado antes de ser passado paraecho). Uma solução alternativa seria escrever\"para os caracteres"internos. Mas não havia nenhuma razão para incluir a coisa toda entre aspas duplas - aspas simples são geralmente preferíveis nos casos em que qualquer uma pode ser usada .A outra mudança - que não foi uma mudança no comando final, mas foi uma alteração que fiz apenas enquanto estava trabalhando nela - foi que eu removi o redirecionamento
>> note.txtaté Eu sabia que tinha o comando certo. Ao enviar a saída para o terminal, imediatamente pude ver qual era o efeito. Eu adicionei novamente o redirecionamento quando terminei.
Isso está estilisticamente mais próximo do que você já tinha, mas não é a única maneira de fazer isso.
Caminho 2: Separe os comandos echo para linhas separadas, em vez de usar -e .
Como a única seqüência que você deseja tratar especialmente por eco é o \n (entre text e on ), você pode usar apenas dois comandos echo separados e (como muru pode estar sugerindo ) não use -e .
Aqui estão duas maneiras de redirecionar a saída de vários comandos:
-
Dois redirecionamentos separados, um para cada comando.
echo 'writes (>> appends) in note.txt this text' >> note.txt echo 'on 2 lines (with "-e" and "\n" help)' >> note.txtSe o nome do arquivo for longo ou se você estiver escrevendo um script e quiser apenas alterá-lo em um só lugar, poderá atribuí-lo a uma variável:
out="/home/ek/Documents/long name that can have spaces as it's quoted/note.txt" echo 'writes (>> appends) in note.txt this text' >> "$out" echo 'on 2 lines (with "-e" and "\n" help)' >> "$out" -
Um redirecionamento único aplicado a um comando composto composto pelos dois comandos.
{ echo 'writes (>> appends) in note.txt this text' echo 'on 2 lines (with "-e" and "\n" help)' } >> note.txtVocê pode colocar isso em uma linha, se quiser, mas se não houver uma nova linha antes da chave de fechamento (
}), um ponto-e-vírgula (;) deve preceder:{ echo 'writes (>> appends) in note.txt this text'; echo 'on 2 lines (with "-e" and "\n" help)'; } >> note.txt
Caminho 3: passe um literal \n para echo em vez de usar -e .
Linhas novas reais podem aparecer entre aspas (simples ou dupla) e são interpretadas literalmente:
echo 'writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)' >> note.txt
Como a primeira linha termina entre aspas, o shell não aceita o final do comando, mas continua lendo.
Se você quiser encaixá-lo em uma única linha, poderá usar $'\n' , que se expande para uma nova linha. Isso é expandido pelo shell antes ser passado para o comando echo , portanto, ele não deve ser citado.
echo 'writes (>> appends) in note.txt this text'$'\n''on 2 lines (with "-e" and "\n" help)' >> note.txt
Caminho 4: use printf
printf é muito poderoso; Há várias maneiras de usá-lo para resolver esse problema. Como estou apresentando isso como uma solução distinta dos outros, aqui está uma boa maneira de usá-lo de uma maneira que você não pode usar echo :
printf '%s\n%s\n' 'writes (>> appends) in note.txt this text' 'on 2 lines (with "-e" and "\n" help)' >> note.txt
A sintaxe geral para printf é printf format args... (onde args... significa zero ou mais argumentos adicionais da linha de comando). A string de formato acima, %s\n%s\n , significa:
-
%s: consuma e imprima o próximo argumento não utilizado (ou seja, primeiro) emargs...(ou seja, sua primeira linha). -
\n: imprima uma nova linha. -
%s: consuma e imprima o próximo argumento não utilizado (ou seja, segundo) emargs...(ou seja, sua segunda linha). -
\n: imprima uma nova linha.
Quando houver mais argumentos após a string de formato do que a string de formato exige, o comando printf recomeça a partir do início da string de formatação. Assim, enquanto menos auto-documentando, você poderia escrever apenas '%s\n' (em vez de '%s\n%s\n' ) para a string de formato, e produziria a mesma saída nesse caso.
Não tentarei documentar amplamente printf aqui. Em vez disso, veja:
- A saída de
help printf. - A
printfda subseção de 4.2 Comandos Bash Builtin em o manual de referência da bash . - Esta página de manual, documentando o comando printf padrão (que bash se estende ligeiramente).
- A função
printf()na biblioteca C padrão, na qual o comandoprintfé baseado, e a qual é referida explicitamente nos recursos acima. A documentação, como esta página , é mais completa e mais acessível do que a maioria das fontes naprintfcomando. E a sintaxe da string de formato é muito semelhante.
Caminho 5: use cat e um documento aqui.
Este caminho é especialmente valioso quando há muitas entradas e scripts. Se você estiver usando o shell de forma interativa ao invés de escrever um script, você pode usar isso, mas por favor considere Way 6 abaixo primeiro.
Enquanto echo e printf imprimem texto com base no conteúdo de seus argumentos de linha de comando, cat imprime o conteúdo de seus arquivos de entrada (conforme especificado na linha de comando) ou, se não houver nenhum (ou passado - ), sua entrada padrão .
Sem redirecionamentos, a entrada padrão é o que você digita no terminal de controle de um programa. Aqui, os documentos são um tipo especial de redirecionamento. As linhas são coletadas até que uma palavra-chave especificada (eu usei EOF ) apareça sozinha em uma linha. Em seguida, as linhas até, mas não incluindo EOF (ou o que você usou) são fornecidas como entrada padrão para o comando que está sendo executado.
cat >> note.txt << EOF
writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)
EOF
Uma das diferenças entre citar " e ' é que a maioria das expansões e substituições com $ (por exemplo, $varname ) são executadas entre aspas duplas, mas nenhuma está entre aspas simples. Há também duas maneiras de usar aqui os documentos, com base em se $ (e também ' e \ ) deve receber um significado especial ou ser tratado literalmente.
Nesse caso, não importa - $ e ' não aparecem, e \ só é tratado especialmente em um documento aqui quando ele escapa de um metacaracteres da casca (não n ). Assim como nas expressões com aspas simples e duplas, as duas formas tratam \n literalmente. (Lembre-se, você precisou usar um recurso especial de echo , ativado por -e , para obter \n tratado especialmente.)
Mas você sabe de outras aplicações:
- A maneira mostrada acima executará expansões e substituições, tratando
$,'e\especialmente quando elas aparecem em um contexto em que seu significado especial se aplica. - Para fazer com que todo o texto seja tratado literalmente, cite a totalidade ou parte da palavra que aparece à direita de
<<com',",\ou uma combinação deles (por exemplo,cat >> note.txt << 'EOF').
Caminho 6: use cat sem nenhum redirecionamento de entrada.
Se você estiver usando o shell interativamente, por padrão, a entrada padrão do shell é do seu terminal. Quando você executa um programa, por padrão, a entrada padrão do programa também é obtida do seu terminal. (Isso pode ser alterado por redirecionamentos de entrada, é claro).
Portanto, se você estiver executando um comando de forma interativa e desejar usar o cat com >> ou > output redirection para enviar dados para um arquivo, não será necessário redirecionar nenhuma entrada. Basta digitar:
cat >> note.txt
writes (>> appends) in note.txt this text
on 2 lines (with "-e" and "\n" help)
^D
Em vez de ^D , não insira um literal ^D . Em vez disso, pressione Ctrl + D . Isso indica ao seu terminal que ele deve informar fim do arquivo (isto é, que quando o programa em execução pede mais informações, é informado que não existe nenhum, como se tivesse chegado ao fim de um arquivo normal armazenado no disco). Quando cat vê que não há mais entrada, ela sai e você retorna ao shell.
Se você estiver escrevendo um script, o Way 6 não funcionará, porque o bash lê os comandos de um arquivo, mas a entrada padrão ainda é (normalmente) uma outra coisa, como seu terminal.
Uma diferença notável entre usar cat com um documento here e usar cat sem redirecionamento de entrada, mesmo quando a entrada padrão é o seu terminal, é isso:
-
cat >> note.txtescreve uma linha por vez paranote.txt. Cada vez que você pressiona Enter , uma linha é gravada emnote.txt. -
cat >> note.txt << EOFleva toda a entrada até a linhaEOF, então anexa anote.txt. Se você interromper a entrada pressionando Ctrl + C , nada será escrito (e senote.txtjá não existir, nem sequer será criado).
, procure pela seção intitulada QUOTING. Veja também a página de manual do comando
.